How I can declare function that takes number and list of numbers, and returns NONE if there is no such number in the list, otherwise returns list option ('Maybe' in Haskell) without this number? If there more then one such number, function has to erase just first of them.
all_except_one : 'a * 'a list -> 'a list option
I have no idea how to do it :\
I ask any code in any language, just some tip about algorithm in functional style (initially I have to solve this problem in SML). Also I can't use higher order functions in my task.
what about this solution ?
fun all_except_one(s, lst) =
let
fun helper e =
case e of
([], _) => NONE
|(x::xs, acc) => if x = s
then SOME (acc # xs)
else helper(xs, x :: acc)
in helper(lst, []) end
The same without helper function and without tail recursion.
fun all_except_one (_, []) = NONE
| all_except_one (s, x::xs) = if x = s
then SOME xs
else case all_except_one(s, xs) of
NONE => NONE
| SOME ys => SOME (x::ys)
How about (Haskell syntax):
allbutone n xs
| n `elem` xs = Just (filter (!=n) xs)
| otherwise = Nothing
Related
I'm writing a function called after which takes a list of integers and two integers as parameters. after list num1 num2 should return True if num1 occurs in the list and num2 occurs in list afternum1. (Not necessarily immediately after).
after::[Int]->Int->Int->Bool
after [] _ _=False
after [x:xs] b c
|x==b && c `elem` xs =True
|x/=b && b `elem` xs && b `elem` xs=True
This is what I have so far,my biggest problem is that I don't know how to force num2 to be after num1.
There's a few different ways to approach this one; while it's tempting to go straight for recursion on this, it's nice to
avoid using recursion explicitly if there's another option.
Here's a simple version using some list utilities. Note that it's a Haskell idiom that the object we're operating over is usually the last argument. In this case switching the arguments lets us write it as a pipeline with it's third argument (the list) passed implicitly:
after :: Int -> Int -> [Int] -> Bool
after a b = elem b . dropWhile (/= a)
Hopefully this is pretty easy to understand; we drop elements of the list until we hit an a, assuming we find one we check if there's a b in the remaining list. If there was no a, this list is [] and obviously there's no b there, so it returns False as expected.
You haven't specified what happens if 'a' and 'b' are equal, so I'll leave it up to you to adapt it for that case. HINT: add a tail somewhere ;)
Here are a couple of other approaches if you're interested:
This is pretty easily handled using a fold;
We have three states to model. Either we're looking for the first elem, or
we're looking for the second elem, or we've found them (in the right order).
data State =
FindA | FindB | Found
deriving Eq
Then we can 'fold' (aka reduce) the list down to the result of whether it matches or not.
after :: Int -> Int -> [Int] -> Bool
after a b xs = foldl go FindA xs == Found
where
go FindA x = if x == a then FindB else FindA
go FindB x = if x == b then Found else FindB
go Found _ = Found
You can also do it recursively if you like:
after :: Int -> Int -> [Int] -> Bool
after _ _ [] = False
after a b (x:xs)
| x == a = b `elem` xs
| otherwise = after a b xs
Cheers!
You can split it into two parts: the first one will find the first occurrence of num1. After that, you just need to drop all elements before it and just check that num2 is in the remaining part of the list.
There's a standard function elemIndex for the first part. The second one is just elem.
import Data.List (elemIndex)
after xs x y =
case x `elemIndex` xs of
Just i -> y `elem` (drop (i + 1) xs)
Nothing -> False
If you'd like to implement it without elem or elemIndex, you could include a subroutine. Something like:
after xs b c = go xs False
where go (x:xs) bFound
| x == b && not (null xs) = go xs True
| bFound && x == c = True
| null xs = False
| otherwise = go xs bFound
I've been solving a few combinatoric problems on Haskell, so I wrote down those 2 functions:
permutations :: (Eq a) => [a] -> [[a]]
permutations [] = [[]]
permutations list = do
x <- list
xs <- permutations (filter (/= x) list)
return (x : xs)
combinations :: (Eq a, Ord a) => Int -> [a] -> [[a]]
combinations 0 _ = [[]]
combinations n list = do
x <- list
xs <- combinations (n-1) (filter (> x) list)
return (x : xs)
Which works as follows:
*Main> permutations [1,2,3]
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
*Main> combinations 2 [1,2,3,4]
[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
Those were uncomfortably similar, so I had to abstract it. I wrote the following abstraction:
combinatoric next [] = [[]]
combinatoric next list = do
x <- list
xs <- combinatoric next (next x list)
return (x : xs)
Which receives a function that controls how to filter the elements of the list. It can be used to easily define permutations:
permutations :: (Eq a) => [a] -> [[a]]
permutations = combinatoric (\ x ls -> filter (/= x) ls)
But I couldn't define combinations this way since it carries an state (n). I could extend the combinatoric with an additional state argument, but that'd become too clunky and I remember such approach was not necessary in a somewhat similar situation. Thus, I wonder: is it possible to define combinations using combinatorics? If not, what is a better abstraction of combinatorics which successfully subsumes both functions?
This isn't a direct answer to your question (sorry), but I don't think your code is correct. The Eq and Ord constraints tipped me off - they shouldn't be necessary - so I wrote a couple of QuickCheck properties.
prop_numberOfPermutations xs = length (permutations xs) === factorial (length xs)
where _ = (xs :: [Int]) -- force xs to be instantiated to [Int]
prop_numberOfCombinations (Positive n) (NonEmpty xs) = n <= length xs ==>
length (combinations n xs) === choose (length xs) n
where _ = (xs :: [Int])
factorial :: Int -> Int
factorial x = foldr (*) 1 [1..x]
choose :: Int -> Int -> Int
choose n 0 = 1
choose 0 r = 0
choose n r = choose (n-1) (r-1) * n `div` r
The first property checks that the number of permutations of a list of length n is n!. The second checks that the number of r-combinations of a list of length n is C(n, r). Both of these properties fail when I run them against your definitions:
ghci> quickCheck prop_numberOfPermutations
*** Failed! Falsifiable (after 5 tests and 4 shrinks):
[0,0,0]
3 /= 6
ghci> quickCheck prop_numberOfCombinations
*** Failed! Falsifiable (after 4 tests and 1 shrink):
Positive {getPositive = 2}
NonEmpty {getNonEmpty = [3,3]}
0 /= 1
It looks like your functions fail when the input list contains duplicate elements. Writing an abstraction for an incorrect implementation isn't a good idea - don't try and run before you can walk! You might find it helpful to read the source code for the standard library's definition of permutations, which does not have an Eq constraint.
First let's improve the original functions. You assume that all elements are distinct wrt their equality for permutations, and that they're distinct and have an ordering for combinations. These constraints aren't necessary and as described in the other answer, the code can produce wrong results. Following the robustness principle, let's accept just unconstrained lists. For this we'll need a helper function that produces all possible splits of a list:
split :: [a] -> [([a], a, [a])]
split = loop []
where
loop _ [] = []
loop rs (x:xs) = (rs, x, xs) : loop (x:rs) xs
Note that the implementation causes prefixes returned by this function to be reversed, but it's nothing we require.
This allows us to write generic permutations and combinations.
permutations :: [a] -> [[a]]
permutations [] = [[]]
permutations list = do
(pre, x, post) <- split list
-- reversing 'pre' isn't really necessary, but makes the output
-- order natural
xs <- permutations (reverse pre ++ post)
return (x : xs)
combinations :: Int -> [a] -> [[a]]
combinations 0 _ = [[]]
combinations n list = do
(_, x, post) <- split list
xs <- combinations (n-1) post
return (x : xs)
Now what they have in common:
At each step they pick an element to output,
update the list of elements to pick from and
stop after some condition is met.
The last point is a bit problematic, as for permutations we end once the list to choose from is empty, while for combinations we have a counter. This is probably the reason why it was difficult to generalize. We can work around this by realizing that for permutations the number of steps is equal to the length of the input list, so we can express the condition in the number of repetitions.
For such problems it's often very convenient to express them using StateT s [] monad, where s is the state we're working with. In our case it'll be the list of elements to choose from. The core of our combinatorial functions can be then expressed with StateT [a] [] a: pick an element from the state and update the state for the next step. Since the stateful computations all happen in the [] monad, we automatically branch all possibilities. With that, we can define a generic function:
import Control.Monad.State
combinatoric :: Int -> StateT [a] [] b -> [a] -> [[b]]
combinatoric n k = evalStateT $ replicateM n k
And then define permutations and combinations by specifying the appropriate number of repetitions and what's the core StateT [a] [] a function:
permutations' :: [a] -> [[a]]
permutations' xs = combinatoric (length xs) f xs
where
f = StateT $ map (\(pre, x, post) -> (x, reverse pre ++ post)) . split
combinations' :: Int -> [a] -> [[a]]
combinations' n xs = combinatoric n f xs
where
f = StateT $ map (\(_, x, post) -> (x, post)) . split
The question is like this:
Write a function that takes an integer list and returns its length and the
second largest integer in the list.
I can solve this with two functions but is there any solution that use only one function to do it?
Any help is appreciated!
Thanks!
Don't make it complicated.
f xs = (sort xs !! 1, length xs)
If you choose to make it complicated, make it complicated in the right way.
Edited to use #ThomasM.DuBuisson's suggestion
You can solve this the same way that you could finding the max: using a fold. Max can be pretty trivially implemented with
mymaximum :: Ord a => [a] -> a
mymaximum xs = foldl searcher (head xs) xs
where
searcher :: Ord a => a -> a -> a
searcher a b
| a > b = a
| otherwise = b
So we can implement it similarly by just keeping up with the two largest values (notice that we have to "seed" the fold with a tuple as well):
nextmaximum :: Ord a => [a] -> a
nextmaximum xs = fst $ foldl searcher (h, h) xs
where
h = head xs
searcher :: (Ord a) => (a, a) -> a -> (a, a)
searcher (s, f) x = (min f (max s x), max f x)
You can just compose individual functions together. This is neither efficient nor robust, but it's sure easy to write:
f xs = maximum . filter (< maximum xs) $ xs
head . (!!1) . group . sortBy (flip compare) $ [1,1,2,3,4,4,4,5,5,6,6,6,6]
5
the question in short: What is the most idiomatic way to do "recursive List comprehension" in F#?
more detailed: As I have learned so far (I am new to F#) we have essentially the following tools to "build up" lists: List.map and list comprehension. Imho they both do more or less the same thing, they generate a list by "altering" the elements of a given list (in case of comprehension the given list is of the form [k..n]).
What I want to do is to inductively build up lists (before people ask: for no other reason than curiosity) i.e. is there any built in function with the behavior one would expect from a function called something like "List.maplist" that might take as arguments
a function f : 'a List -> 'a and an n : int,
returning the list
[... ; f (f []) ; f [] ] of length n.
To illustrate what I mean I wrote such a function on my own (as an exercise)
let rec recListComprehension f n =
if n=0 then []
else
let oldList = recListComprehension f (n-1)
f (oldList) :: oldList
or a bit less readable but in turn tail recursive:
let rec tailListComprehension f n list =
if n=0 then list
else tailListComprehension f (n-1) ((f list)::list)
let trecListComprehension f n = tailListComprehension f n []
for example, a list containing the first 200 fibonacci numbers can be generated by
let fiboGen =
function
| a::b::tail -> a+b
| _ -> 1UL
trecListComprehension (fiboGen) 200
to sum up the question: Is there a build in function in F# that behaves more or less like "trecListComprehension" and if not what is the most idiomatic way to achieve this sort of functionality?
PS: sorry for being a bit verbose..
What is the most idiomatic way to do "recursive List comprehension" in F#?
It's the matter of style. You will encounter high-order functions more often. For certain situations e.g. expressing nested computation or achieving laziness, using sequence expression seems more natural.
To illustrate, your example is written in sequence expression:
let rec recListComprehension f n = seq {
if n > 0 then
let oldList = recListComprehension f (n-1)
yield f oldList
yield! oldList }
recListComprehension fiboGen 200 |> Seq.toList
You have a very readable function with both laziness and tail-recursiveness which you can't easily achieve by using Seq.unfold.
Similarly, nested computation of cartesian product is more readable to use sequence expression / list comprehension:
let cartesian xs ys =
[ for x in xs do
for y in ys do
yield (x, y) ]
than to use high-order functions:
let cartesian xs ys =
List.collect (fun x -> List.map (fun y -> (x, y)) ys) xs
I once asked about differences between list comprehension and high-order functions which might be of your interest.
You're basically folding over the numeric range. So it could be written:
let listComp f n = List.fold (fun xs _ -> f xs :: xs) [] [1 .. n]
This has the added benefit of gracefully handling negative values of n.
You could do a Seq.unfold and then do Seq.toList.
See the example from here:
let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20."
for x in seq1 do printf "%d " x
let fib = Seq.unfold (fun state ->
if (snd state > 1000) then None
else Some(fst state + snd state, (snd state, fst state + snd state))) (1,1)
printfn "\nThe sequence fib contains Fibonacci numbers."
for x in fib do printf "%d " x
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 10 months ago.
Improve this question
I'm working through Real World Haskell, and at the moment doing the exercises at the end of Chapter 3.
I'm taking an unusual approach: even though I know there are some language features they haven't covered yet that would help me, I am trying to do these exercises using only things they have explicitly covered. Why? Just kind of for fun really. It feels like it is forcing me to give my brain some extra practice with recursion.
So I just completed the exercise posed as follows: "Create a function that sorts a list of lists based on the length of each sublist. (You may want to look at the sortBy function from the Data.List module.)"
Now, they threw in the hint about the Data.List module. But they didn't say a word about where reference doc can be found, about how to import stuff, etc. So I decided to roll my own sort just to see if I could do it. I used Bubble Sort since it's the simplest algorithm.
The result is below. I'd like to get you Haskell gurus to critique it please ... but with the following caveat in mind: If you suggest improvements, please base them on language features covered through chapter 3 of Real World Haskell (or what you guess those features might be without going to the trouble of looking it up). I know there are tons of awesome language features waiting for me that will let me make this code better, but right now the specific challenge was to do it with the "primitive" features covered so far.
I'm sure there are cases where I'm reaching around my shoulder to scratch my elbow, cases where I'm using explicit control flow when recursion and pattern matching could do more for me, etc. I'm sure the code could be made much shorter and more readable too. I bet there are good idioms I don't know about that can be used with the primitive language features I'm limiting myself to. Those are the kinds of tips I'd love to receive.
This is probably the ugliest code I'm proud of in any language (at least, that I can remember). My first stab, in a functional language, at something beyond "Hello, world" type stuff. And now you are going to beat the crap out of it :) . Be gentle, please, but I'm looking forward to some meaty insight. Thanks.
areListsEqual :: (Eq a) => [a] -> [a] -> Bool
areListsEqual [] [] = True
areListsEqual [] _ = False
areListsEqual _ [] = False
areListsEqual xs ys = (head xs == head ys) && (areListsEqual (tail xs) (tail ys))
charlieSort :: (Eq a) => [[a]] -> [[a]]
charlieSort [] = []
charlieSort (x:xs) | null xs = [x]
charlieSort xs | (length xs) >= 2 = if(not (areListsEqual xs wip))
then charlieSort wip
else wip
where
first = head xs
second = head (tail xs)
theRest = drop 2 xs
swapPairIfNeeded a b = if(length a >= length b)
then [second, first]
else [first, second]
modifiedPair = swapPairIfNeeded first second
wip = (take 1 modifiedPair) ++ charlieSort ( (drop 1 modifiedPair) ++ theRest)
I would first and foremost start using pattern-matching.
areListsEqual :: Eq a => [a] -> [a] -> Bool
areListsEqual [ ] [ ] = True
areListsEqual [ ] _ = False
areListsEqual _ [ ] = False
areListsEqual (x:xs) (y:ys) = x == y && areListsEqual xs ys
Note how much more readable this is, when head and tail is avoided.
charlieSort :: Eq a => [[a]] -> [[a]]
charlieSort [ ] = []
charlieSort [x ] = [x]
charlieSort xs#(first:second:theRest)
| areListsEqual xs wip = wip
| otherwise = charlieSort wip
where
swapPairIfNeeded a b
| length a >= length b = [second,first]
| otherwise = [first,second]
modifiedPair = swapPairIfNeeded first second
wip = take 1 modifiedPair ++ charlieSort (drop 1 modifiedPair ++ theRest)
I changed the if-then-else to a guard for slightly improved readability
(YMMV). Instead of checking that the list has at least two elements with a
call to length we use pattern-matching, which also allows us to name
first,second,theRest directly. The name # pattern pattern both
matches the input against pattern and names the whole input as name.
Now, I want to avoid using take and drop for extracting the two elements
of modifiedPair, so the last two lines are changed into
[shorter,longer] = swapPairIfNeeded first second
wip = [shorter] ++ charlieSort ([longer] ++ theRest)
where you could write the last line as
wip = shorter : charlieSort (longer : theRest)
if you preferred. But why should swapPairIfNeeded return the shorter and
the longer of the first and second list in a list ? Why not use a
pair like
swapPairIfNeeded a b
| length a >= length b = (second,first)
| otherwise = (first,second)
(shorter,longer) = swapPairIfNeeded first second
? In most circumstances, it is better to use tuples for fixed number of
values (possibly of differing types) and to use lists for variable number of
values (necessarily of same type). But it seems strange that
swapPairIfNeeded compares its arguments a and b, but then returns
first and second anyway. In this case, instead of letting it return a
and b in a pair, I will remove swapPairIfNeeded altogether instead :
(shorter,longer)
| length first >= length second = (second,first)
| otherwise = (first,second)
"unfolding" the body of swapPairIfNeeded into the definition of
(shorter,longer).
So now the code of charlieSort looks like
charlieSort :: Eq a => [[a]] -> [[a]]
charlieSort [ ] = []
charlieSort [x ] = [x]
charlieSort xs#(first:second:theRest)
| areListsEqual xs wip = wip
| otherwise = charlieSort wip
where
(shorter,longer)
| length first >= length second = (second,first)
| otherwise = (first,second)
wip = shorter : charlieSort (longer : theRest)
Finally, I should remark that charlieSort doesn't really implement
bubble-sort, because the recursive call to charlieSort will not only
make one "bubble-up" pass along the list, but also fully sort the list
longer : theRest, so that all that has to be done after this recursive call
(before returning one "level up") is to possibly percolate shorter to its
rightful place.
Charlie: I'll confine myself to a single critique: never use head, tail, or length if you can use pattern matching:
areListsEqual [] [] = True
areListsEqual (x:xs) (y:ys) = x == y && areListsEqual xs ys
areListsEqual _ _ = False
I can't follow your sort algorithm (and it would be courteous of you to reformat your question so as to eliminate the horizontal scroll bar), but I'd rewrite the first three lines like this:
charlieSort [] = []
charlieSort [x] = x
charlieSort (x1:x2:xs) = if ...
(P.S. All uses of head and tail can be rewritten using pattern matching, and beginners should do so. Not all uses of length can be replaced by pattern matching, but common noob codes like length xs == 0 or length xs >= 2 can and should be rewritten.)
(P.P.S. Even experienced Haskell programmers seldom use 'head'. Less than two-tenths of one percent of source lines in the Glasgow Haskell compiler mention 'head', and eyeballing those mentions, roughly half are in string literals or comments. That's approximately one use of 'head' for every 1500 lines of code.)
You don't need the areListsEqual function. You can compare lists with the (==) function. And I'd use a quicksort rather than bubblesort. Here's a solution that I think uses only what you should have learned so far.
charlieSort :: (Eq a) => [[a]] -> [[a]]
charlieSort [] = []
charlieSort (x:xs) = charlieSort (filter (cmpLen (>) x) xs) ++ [x] ++
charlieSort (filter (cmpLen (<=) x) xs)
where filter _ [] = []
filter p (x:xs) = (if (p x) then (x:) else id) (filter p xs)
cmpLen f x y = f (length x) (length y)
I'm on chapter 8, so I'm no old hand, but I'd prefer
areListsEqual x:xs y:ys = (x == y) && (areListsEqual xs ys)
areListsEqual [] [] = True
areListsEqual _ _ = False
It seems a bit more in line with Haskell style.
Similarly,
charlieSort [] = []
charlieSort (x:[]) = [x]
charlieSort (x1:x2:xs) = blah blah
swapPairIfNeed works as is because you only call it with first and second as its arguments (in that order), but you probably meant
swapPairIfNeed a b = if (length a >= length b)
then [b, a]
else [a, b]
In fact, I prefer the third case of charlieSort to look like
charlieSort (x1:x2:xs) = if not (areListsEqual x1:x2:xs wip)
then charlieSort wip
else wip
where swapPairIfNeeded a b = if (length a >= length b)
then (b, a)
else (a, b)
wip = f (swapPairIfNeeded first second)
f (a, b) = a : (charlieSort b:xs)
I think this was all covered by chapter 3.
Now, let's examine the algorithm. Even holding ourselves to bubble sort, there's no need to check the whole list after sorting. Instead, we can swap the first two elements if necessary, then sort the tail of the list. If the head is shorter than the head of the sorted tail, we're done.
charlieSort (x1:x2:xs) = if (length a <= length (head sortedTail))
then a : sortedTail
else charlieSort (a : sortedTail)
where sortedTail = charlieSort (b:xs)
(a, b) = if (length x1 >= length x2)
then (x2, x1)
else (x1, x2)
You claim that bubble sort is the easiest sorting algorithm, but that's not quite the case here. Bubble sort is great for arrays, where you index into them linearly. For Haskell's linked lists, insertion sort is actually much prettier to look at.
Let's start with the insert function:
winsert :: [a] -> [[a]] -> [[a]]
winsert x [] = [x]
winsert x (y:ys)
| length x < length y = x : y : ys
| otherwise = y : winsert x ys
If the list is empty, put x into it
If the list isn't empty:
If x < y, then x belongs at the front of the list
Otherwise, the head of the list is y, and the tail is made of up x being inserted somewhere into ys.
Next, we have the actual sorting function:
wsort :: [[a]] -> [[a]]
wsort [] = []
wsort [x] = [x]
wsort (x:xs) = winsert x (wsort xs)
If the list is empty, return it
If the list has only one item, it doesn't need to be sorted
If the list is longer than that, sort xs, then insert x into the now sorted xs
Interestingly, by modifying winsert to take a function as an argument (in place of length), wsort could be used to sort based on all kinds of criteria. Try making one that sort a list of lists based on the sum of each sublist.