SML length function:
fun length(L) =
if (L=nil) then 0
else 1+length(tl(L));
For example:
length [1,2,3] = 3;
length [ [5], [4], [3], [2,1] ] = 4;
Based on the code, how do I change it if I also want to count the elements in the list of the list?
For example:
length [ [5], [4], [3], [2,1] ] = 5;
You could create another function that will use your function as follows:
fun d_length ( [] ) = 0
| d_length ( l :: l' ) = length(l) + d_length(l');
d_length[ [5], [4], [3], [2,1] ];
Or alternatively, use the build in reducer:
List.foldl (fn(e,a) => length(e) + a) 0 [ [5], [4], [3], [2,1] ];
You don't want to make the comparison L=nil as this only works for lists of types that are comparable (e.g. not lists of functions). Rather, you want the pattern matching that Kevin Johnson suggests;
fun length [] = 0
| length (x::xs) = 1 + length xs
Or using tail-recursion:
fun length xs =
let fun len [] n = n
| len (x::xs) n = len xs (1+n)
in len xs 0 end
Unlike length : 'a list -> int, this function has type 'a list list -> int.
The combined length of all sublists can be achieved in a number of ways. E.g.
fun length2 xss = List.foldl op+ 0 (List.concat xss)
But as Kevin's answer also takes advantage of, there really isn't any point in building a new list with List.concat xss when all we do is destroy it again moments later. So to shamelessly rip his solution:
fun length2 xss = List.foldl (fn (xs, sum) => length xs + sum) 0 xss
which is probably the most readable way to express that function, too, but if you were to try to code golf that function really short, you could also rewrite the inner closure using higher-order functions:
fun curry f x y = f (x, y)
fun uncurry f (x, y) = f x y
fun length2 xss = List.foldl (uncurry (curry op+ o length)) 0 xss
Here is a pattern-matching straight recursion version which doesn't use the built-in length function but instead computes the total length ("tol") directly:
fun tol [] = 0
| tol ([]::xss) = tol xss
| tol ((x::xs)::xss) = 1 + tol (xs::xss);
The order of parenthesis in the final clause is important. It overrides the right-associativity of :: so that the x in (x::xs)::xss is interpreted as the head of the first list in xss rather than head of xss itself.
The pattern of these answers seems to be to close with a fold, and I don't want to break pattern. Here is a fold which folds into a sum a list obtained by mapping length over a list of lists:
fun tol xss = foldl op+ 0 (map length xss);
Related
I am new to F# & tuples and I am trying to split a list into three lists of tuples using recursion and matching.
For example, a list of [1; 2; 3] would return:
l1 = [1]
l2 = [2]
l3 = [3]
or
[1;2;3;4;5;6;7]:
l1 = [1;2;3]
l2 = [4; 5]
l3 = [6; 7]
So far my code starts out as
let rec split x =
match x with
| _ -> [], [], []
I'm not sure where to start when inserting elements into each list.
The most basic approach would be to walk over the list, process the rest of it recursively and then append the current element to one of the three returned lists. You will need to add an extra parameters i to the function to keep track of how far in the list you are (and then use this to determine where should the current elemnt go). The general structure in the most basic form is:
let split l =
let length = List.length l
let rec loop i l =
match l with
| [] ->
// Empty list just becomes a triple of empty lists
[], [], []
| x::xs ->
// Process the rest of the list recursively. This
// gives us three lists containing the values from 'xs'
let l1, l2, l3 = loop (i + 1) xs
// Now comes the tricky bit. Here you need to figure out
// whether 'x' should go into 'l1', 'l2' or 'l3'.
// Then you can append it to one of them using something like:
l1, x::l2, l3
// Walk over the list, starting with index 'i=0'
loop 0 l
What to do about the tricky bit? I do not have a solution that works exactly as you wanted, but the following is close - it simply looks whether i is greater than 1/3 of the length or 2/3 of the length:
let split l =
let length = List.length l
let rec loop i l =
match l with
| [] -> [], [], []
| x::xs ->
let l1, l2, l3 = loop (i + 1) xs
if i >= length / 3 * 2 then l1, l2, x::l3
elif i >= length / 3 then l1, x::l2, l3
else x::l1, l2, l3
loop 0 l
This will always create groups of length / 3 and put remaining elements in the last list:
split [1..3] // [1], [2], [3]
split [1..4] // [1], [2], [3; 4]
split [1..5] // [1], [2], [3; 4; 5]
split [1..6] // [1; 2], [3; 4], [5; 6]
You should be able to adapt this to the behaviour you need - there is some fiddly calculation that you need to do to figure out exactly where the cut-off points are, but that's a matter of getting the +/-1s right!
There is a function for that in the List module.
You can test it easily in F# interactive (fsi).
let input = [1;2;3];;
let output = List.splitInto 3 input;;
output;;
val it : int list list = [[1]; [2]; [3]]
So it returns a list of lists.
If you want to do it by hand, you can still use other list functions (which might be good exercise in itself):
let manualSplitInto count list =
let l = List.length list
let n = l / count
let r = l % count
List.append
[(List.take (n+r) list)]
(List.unfold (fun rest ->
match rest with
| [] -> None
| _ -> let taken = min n (List.length rest)
Some (List.take taken rest, List.skip taken rest))
(List.skip (n+r) list))
Here, List.unfold does the iteration (recursing) part for you.
So, if you really want to train working with recursive functions, you will end up writing your own List.unfold replacement or something more tailored to your concrete use case.
let pedestrianSplitInto count list =
let l = List.length list
let n = l / count
let r = l % count
let rec step rest acc =
match rest with
| [] -> acc
| _ ->
let taken = min n (List.length rest)
step (List.skip taken rest) ((List.take taken rest) :: acc)
List.rev (step (List.skip (n+r) list) [List.take (n+r) list])
Please observe how similar the implementation of function step is to the lambda given to List.unfold in manualSplitInto.
If you also do not want to use functions like List.take or List.skip, you will have to go even lower level and do element wise operations, such as:
let rec splitAtIndex index front rear =
match index with
| 0 -> (List.rev front, rear)
| _ -> splitAtIndex (index - 1) ((List.head rear) :: front) (List.tail rear)
let stillLivingOnTreesSplitInto count list =
let l = List.length list
let n = l / count
let r = l % count
let rec collect result (front,rear) =
match rear with
| [] -> (front :: result)
| _ -> collect (front :: result) (splitAtIndex n [] rear)
let x = splitAtIndex (n+r) [] list
collect [] x |> List.rev
If you know it will always be triplets then this should work.
let xs = [1..7]
let n = List.length xs
let y = List.mapi (fun i x -> (x, 3 * i / n)) xs
List.foldBack (fun (x, i) (a,b,c) -> match i with 0 -> (x::a,b,c) | 1 -> (a,x::b,c) | 2 -> (a,b,x::c)) y (([],[],[]))
I am trying to count the number of non-empty lists in a list of lists with recursive code.
My goal is to write something simple like:
prod :: Num a => [a] -> a
prod [] = 1
prod (x:xs) = x * prod xs
I already have the deifniton and an idea for the edge condition:
nonEmptyCount :: [[a]] -> Int
nonEmptyCount [[]] = 0
I have no idea how to continue, any tips?
I think your base case, can be simplified. As a base-case, we can take the empty list [], not a singleton list with an empty list. For the recursive case, we can consider (x:xs). Here we will need to make a distinction between x being an empty list, and x being a non-empty list. We can do that with pattern matching, or with guards:
nonEmptyCount :: [[a]] -> Int
nonEmptyCount [] = 0
nonEmptyCount (x:xs) = -- …
That being said, you do not need recursion at all. You can first filter your list, to omit empty lists, and then call length on that list:
nonEmptyCount :: [[a]] -> Int
nonEmptyCount = length . filter (…)
here you still need to fill in ….
Old fashion pattern matching should be:
import Data.List
nonEmptyCount :: [[a]] -> Int
nonEmptyCount [] = 0
nonEmptyCount (x:xs) = if null x then 1 + (nonEmptyCount xs) else nonEmptyCount xs
The following was posted in a comment, now deleted:
countNE = sum<$>(1<$)<<<(>>=(1`take`))
This most certainly will look intimidating to the non-initiated, but actually, it is equivalent to
= sum <$> (1 <$) <<< (>>= (1 `take`))
= sum <$> (1 <$) . (take 1 =<<)
= sum . fmap (const 1) . concatMap (take 1)
= sum . map (const 1) . concat . map (take 1)
which is further equivalent to
countNE xs = sum . map (const 1) . concat $ map (take 1) xs
= sum . map (const 1) $ concat [take 1 x | x <- xs]
= sum . map (const 1) $ [ r | x <- xs, r <- take 1 x]
= sum $ [const 1 r | (y:t) <- xs, r <- take 1 (y:t)] -- sneakiness!
= sum [const 1 r | (y:_) <- xs, r <- [y]]
= sum [const 1 y | (y:_) <- xs]
= sum [ 1 | (_:_) <- xs] -- replace each
-- non-empty list
-- in
-- xs
-- with 1, and
-- sum all the 1s up!
= (length . (take 1 =<<)) xs
= (length . filter (not . null)) xs
which should be much clearer, even if in a bit sneaky way. It isn't recursive in itself, yes, but both sum and the list-comprehension would be implemented recursively by a given Haskell implementation.
This reimplements length as sum . (1 <$), and filter p xs as [x | x <- xs, p x], and uses the equivalence not (null xs) === (length xs) >= 1.
See? Haskell is fun. Even if it doesn't yet feel like it, but it will be. :)
I have list of lists of Int and I need to add an Int value to the last list from the list of lists. How can I do this? My attempt is below
f :: [[Int]] -> [Int] -> Int -> Int -> Int -> [[Int]]
f xs [] cur done total = [[]]
f xs xs2 cur done total = do
if total >= length xs2 then
xs
else
if done == fib cur then
f (xs ++ [[]]) xs2 (cur + 1) 0 total
else
f ((last xs) ++ [[xs2!!total]]) xs2 cur (done + 1) (total + 1)
The problem is:
We have a list A of Int
And we need to slpit it on N lists B_1 ,..., B_n , length of B_i is i-th Fibonacci number.
If we have list [1 , 2 , 3 , 4 , 5 , 6 , 7] (xs2 in my code)
The result should be [[1] , [2] , [3 , 4] , [5 , 6 , 7]]
The easy way to deal with problems like this is to separate the problem into sub-problems. In this case, you want to change the last item in a list. The way you want to change it is by adding an item to it.
First let's tackle changing the last item of a list. We'll do this by applying a function to the last item, but not to any other items.
onLast :: [a] -> (a -> a) -> [a]
onLast xs f = go xs
where
go [] = []
go [x] = [f x]
go (x:xs) = x:go xs
You want to change the last item in the list by adding an additional value, which you can do with (++ [value]).
Combining the two with the value you want to add (xs2!!total) we get
(onLast xs (++ [xs2!!total]))
f :: [[Int]] -> Int -> [[Int]]
f [] _ = []
f xs i = (take n xs) ++ [[x + i | x <- last xs]]
where n = (length xs) - 1
last = head . (drop n)
For example,
*Main> f [[1, 2, 3], [], [4, 5, 6]] 5
[[1,2,3],[],[9,10,11]]
*Main> f [[1, 2, 3]] 5
[[6,7,8]]
*Main> f [] 3
You approach uses a do block, this is kind of weird since do blocks are usually used for monads. Furthermore it is rather unclear what cur, done and total are doing. Furthermore you use (!!) :: [a] -> Int -> a and length :: [a] -> Int. The problem with these functions is that these run in O(n), so it makes the code inefficient as well.
Based on changed specifications, you want to split the list in buckets with length the Fibonacci numbers. In that case the signature should be:
f :: [a] -> [[a]]
because as input you give a list of numbers, and as output, you return a list of numbers. We can then implement that as:
f :: [a] -> [[a]]
f = g 0 1
where g _ _ [] = []
g a b xs = xa : g b (a+b) xb
where (xa,xb) = splitAt b xs
This generates:
*Main> f [1,2,3,4,5,6]
[[1],[2],[3,4],[5,6]]
*Main> f [1,2,3,4,5,6,7]
[[1],[2],[3,4],[5,6,7]]
*Main> f [1,2,3,4,5,6,7,8]
[[1],[2],[3,4],[5,6,7],[8]]
*Main> f [1,2,3,4,5,6,7,8,9]
[[1],[2],[3,4],[5,6,7],[8,9]]
The code works as follows: we state that f = g 0 1 so we pass the arguments of f to g, but g also gets an 0 and a 1 (the first Fibonacci numbers).
Each iteration g checks whether we reached the end of the list. If so, we return an empty list as well. Otherwise we determine the last Fibonacci number that far (b), and use a splitAt to obtain the first b elements of the list we process, as well as the remainder. We then emit the first part as head of the list, and for the tail we calculate the next Fibonacci number and pass that to g with the tail of splitAt.
Trying to write a recursive function that will cut a list by n. Then return 2 lists. So if I pass
cut(2, [5;10;4;2;7]);;
val it : int list * int list = ([5; 10], [4; 2; 7])
I would like to get something like that.
let rec cut (n, xs) =
match n, xs with
| 0, xt -> (n, xs)
| n, x::xt -> cut(n, xt), xs;;
Please help.
I'll ad an explanation of #MisterMetaphors recursive function.
The cut function isn't recursive but aux is, it works by counting down from n and removing elements from the head of the list passed to cut.
Say you call cut like this cut 2 [ 3; 4; 5; 7; 8 ]. aux is a pattern matching function taking three arguments: n, partition 1, partition 2. Partition 1 starts out with being an empty list and partition 2 starts out with being the full list passed to cut.
First time aux will match the second clause, then it'll call itself with arguments (1, [3], [4; 5; 7; 8]). Next time it'll also match second clause, now it calls itself with (0, [4; 3], [5; 7; 8]). Third and final time it matches first clause (n=0) and it will return a tuple containing xs and ys.
Notice however that the elements of the xs is in reverse order since each element was prepended (using cons operator ::). The reason this is done is because it's an O(1) operation compared to the append operator # which is O(n) on the left side.
Since xs is in reverse order the last expression in the function is a reversal of xs.
An alternative and slightly short definition could be:
let cut n xs =
let rec aux = function
| 0, xs, ys -> List.rev xs, ys
| n, xs, y :: ys -> aux (n - 1, y :: xs, ys)
| _ -> failwith "invalid arguments"
aux (n, [], xs)
It's probably better to combine built-in functions on lists or sequences to achieve this:
let cut' (n, xs) =
Seq.take n xs, Seq.skip n xs
Recursively, your function can be defined like so:
let cut (n, xs) =
let rec aux = function
| 0, xs, ys -> xs, ys
| n, xs, y :: ys -> aux (n - 1, y :: xs, ys)
| _ -> failwith "invalid arguments"
let l, r = aux (n, [], xs)
(List.rev l, r)
I would like to implement a function that takes as input a size n and a list. This function will cut the list into two lists, one of size n and the rest in another list. I am new to this language and have a hard time learning the syntax.
The main problem I have is that is finding a way to express a size of the list without using any loops or mutable variables.
Can anyone give a me some pointers?
Let's start with the function's type signature. Since it gets n and a list as arguments and returns a pair of lists, you have a function split:
val split : int -> 'a list -> 'a list * 'a list
Here is one approach to implement this function:
let split n xs =
let rec splitUtil n xs acc =
match xs with
| [] -> List.rev acc, []
| _ when n = 0 -> List.rev acc, xs
| x::xs' -> splitUtil (n-1) xs' (x::acc)
splitUtil n xs []
The idea is using an accumulator acc to hold elements you have traversed and decreasing n a long the way. Because elements are prepended to acc, in the end you have to reverse it to get the correct order.
The function has two base cases to terminate:
There's no element left to traverse (xs = [] at that point).
You have gone through the first n elements of the list (n decreases to 0 at that time).
Here is a short illustration of how split computes the result:
split 2 [1; 2; 3] // call the auxiliary function splitUtil
~> splitUtil 2 [1; 2; 3] [] // match the 3rd case of x::xs'
~> splitUtil 1 [2; 3] [1] // match the 3rd case of x::xs'
~> splitUtil 0 [3] [2; 1] // match the 2nd case of n = 0 (base case)
~> List.rev [2; 1], [3] // call List.rev on acc
~> [1; 2], [3]
let split n list =
let rec not_a_loop xs = function
| (0, ys) | (_, ([] as ys)) -> (List.rev xs), ys
| (n, x::ys) -> not_a_loop (x::xs) (n-1, ys)
not_a_loop [] (n, list)
New solution - splitAt is now built into List and Array. See commit around 2014 on github. I noticed this today while using F# in VS.2015
Now you can simply do this...
let splitList n list =
List.splitAt n list
And as you might expect the signature is...
n: int -> list: 'a list -> 'a list * 'a list
Example usage:
let (firstThree, remainder) = [1;2;3;4;5] |> (splitList 3)
printfn "firstThree %A" firstThree
printfn "remainder %A" remainder
Output:
firstThree [1; 2; 3]
remainder [4; 5]
Github for those interested: https://github.com/dsyme/visualfsharp/commit/1fc647986f79d20f58978b3980e2da5a1e9b8a7d
One more way, using fold:
let biApply f (a, b) = (f a, f b)
let splitAt n list =
let splitter ((xs, ys), n') c =
if n' < n then
((c :: xs, ys), n' + 1)
else
((xs, c :: ys), n' + 1)
List.fold splitter (([], []), 0) list
|> fst
|> biApply List.rev
Here is a great series on folds than you can follow to learn more on the topic.