Tail Recursive Combinations - f#

I have this code:
let rec combinations acc listC =
match listC with
| [] -> acc
| h::t ->
let next = [h]::List.map (fun t -> h::t) acc # acc
combinations next t
It looks tail recursive, but I keep getting stack overflows with it. Any ideas on how to make it work?

combinations is tail recursive. Your problem is with the # operator. Appending a list with it iterates the whole list, so as your acc becomes large, you will get a SO.
You can see here, that the # operator is not tail recursive. The non-optimized version looks like: let rec (#) x y = match x with [] -> y | (h::t) -> h :: (t # y).
To get around this problem, there are a couple of options:
If you don't care about order, you could write a tail-recursive method to prepend the result like this:
let rec prepend lst1 lst2 =
match lst1 with
| [] -> lst2
| head::tail -> prepend tail (head::lst2)
> prepend [1;2;3;4] [5;6;7;8];;
val it : int list = [4; 3; 2; 1; 5; 6; 7; 8]
If you care about order, you could write a method to first reverse the list and then prepend it. The drawback of this, of course, is that it will require twice as much memory since you are allocating an additional list to hold the reversed version of the original list. You can reuse the previous function to write something like this:
let prepend2 lst1 lst2 =
prepend (prepend lst1 []) lst2
> prepend2 [1;2;3;4] [5;6;7;8];;
val it : int list = [1; 2; 3; 4; 5; 6; 7; 8]

Related

In this F# code how is the firstElem getting a value?

In the below F# code how the firstElem getting a value? I got the code from the below this link.
let rec quicksort list =
match list with
| [] -> // If the list is empty
[] // return an empty list
| firstElem::otherElements -> // If the list is not empty
let smallerElements = // extract the smaller ones
otherElements
|> List.filter (fun e -> e < firstElem)
|> quicksort // and sort them
let largerElements = // extract the large ones
otherElements
|> List.filter (fun e -> e >= firstElem)
|> quicksort // and sort them
// Combine the 3 parts into a new list and return it
List.concat [smallerElements; [firstElem]; largerElements]
Your text indentation somehow got messed up when copying the text. In the original code from the link the let bindings of smallerElements and largerElements are both further indented than the match | firstElem::otherElements ->. So the answer is that firstElem gets its value from the matching with the head of the parameter/variable list.
Edit: The term head refers to the Head and the Tail of a list. The Head is the first element, and the Tail is all of the rest of the elements. E.g.
let ns = [1; 2; 3; 4]
let h = ns.Head
let t = ns.Tail
will return
val ns : int list = [1; 2; 3; 4]
val h : int = 1
val t : int list = [2; 3; 4]
with the caveat that Head and Tail is not defined for an empty list.
The lines
match list with
| firstElem::otherElements ->
will match the Head of list with firstElem and the Tail with otherElements.

Reversing a list then adding new item

I am trying to learn F#, and I'm trying to create some simple functions as part of this learning.
I have created a function that adds an item to a list then reverses the result. This works very nicely in the F# interactive window in Visual Studio
let addThenReverse n list =
match list with
| [] -> []
| _ -> n::list |> List.rev
addThenReverse 0 [1;2;3] //results in [3; 2; 1; 0]
But I'm having difficulty with writing a function that would reverse a list then add an item to it.
let reverseThenAdd n list =
match list with
| [] -> []
| _ -> List.rev list |> n::list
reverseThenAdd 9 [1;2;3] //desired result [3; 2; 1; 9]
EDIT
The desired result for the above should be [9; 3; 2; 1]. Well done to those who spotted this!
This second function does not compile and I receive the warning 'This expression was expected to have type 'a list -> 'b list but here has type 'c list'
Any variants I try seem to result other compilation errors. I assume (but don't know how) that I need to use the new list created as a result of 'List.rev list', perhaps by assigning it to a variable.
The issue is that you are passing the reversed list to a concatenation expression, and that throws off the compiler. You should do:
let reverseThenAdd n list =
match list with
| [] -> []
| _ -> n :: (List.rev list)
reverseThenAdd 9 [1;2;3] //desired result [3;2;1;9]
which means that you are adding n to the list resulting from (List.rev list)
I'm a little confused by your desired results. Luiso has a version of your code that will fix the compiler, but it won't fit your desired result. With
let reverseThenAdd n list =
match list with
| [] -> []
| _ -> n :: (List.rev list)
reverseThenAdd 9 [1;2;3] //desired result [3; 2; 1; 9]
the actual result will be [9; 3; 2; 1]. If the comment is a typo, and that is in fact your desired result, then Luiso's answer works. Otherwise, there is no material difference between addThenReverse and reverseThenAdd, because "add" means something different (appending and prepending) in each case.
Note that I think in both cases, the first case should be
| [] -> [n]
rather than
| [] -> []
In fact, I don't think you need the match statement at all. I think the mathematically correct formulation would be:
let addThenReverse n list = n::list |> List.rev
let reverseThenAdd n list = n::(list |> List.rev)
Then you would have
addThenReverse 0 [] // result: [0]
reverseThenAdd 0 [] // result: [0]
addThenReverse 9 [1; 2; 3] // result: [3; 2; 1; 9]
reverseThenAdd 9 [1; 2; 3] // result: [9; 3; 2; 1]
ADDENDUM
I'm a fan of expressive code. As elegant as F# is, it is still possible to write code that obscures what you're actually trying to do. The code above works, but you can make it more expressive, and learn a bit more about how the language works, by using the composition operator:
let add n list = n::list
let reverse = List.rev
let addThenReverse n = add n >> reverse
let reverseThenAdd n = reverse >> add n
This gives the same results as before, but it expresses what you're doing more clearly. True to the spirit of functional programming, you're telling the compiler what to do, rather than how to do it.
let reverseThenAdd n list = List.rev list # [n]

Tail Recursive map f#

I want to write a tail recursive function to multiply all the values in a list by 2 in F#. I know there is a bunch of ways to do this but i want to know if this is even a viable method. This is purely for educational purposes. I realize that there is a built in function to do this for me.
let multiply m =
let rec innerfunct ax = function
| [] -> printfn "%A" m
| (car::cdr) -> (car <- car*2 innerfunct cdr);
innerfunct m;;
let mutable a = 1::3::4::[]
multiply a
I get two errors with this though i doubt they are the only problems.
This value is not mutable on my second matching condition
and
This expression is a function value, i.e. is missing arguments. Its type is 'a list -> unit. for when i call length a.
I am fairly new to F# and realize im probably not calling the function properly but i cant figure out why. This is mostly a learning experience for me so the explanation is more important than just fixing the code. The syntax is clearly off, but can i map *2 to a list just by doing the equivalent of
car = car*2 and then calling the inner function on the cdr of the list.
There are a number of issues that I can't easily explain without showing intermediate code, so I'll try to walk through a commented refactoring:
First, we'll go down the mutable path:
As F# lists are immutable and so are primitive ints, we need a way to mutate that thing inside the list:
let mutable a = [ref 1; ref 3; ref 4]
Getting rid of the superfluous ax and arranging the cases a bit, we can make use of these reference cells:
let multiply m =
let rec innerfunct = function
| [] -> printfn "%A" m
| car :: cdr ->
car := !car*2
innerfunct cdr
innerfunct m
We see, that multiply only calls its inner function, so we end up with the first solution:
let rec multiply m =
match m with
| [] -> printfn "%A" m
| car :: cdr ->
car := !car*2
multiply cdr
This is really only for it's own purpose. If you want mutability, use arrays and traditional for-loops.
Then, we go up the immutable path:
As we learnt in the mutable world, the first error is due to car not being mutable. It is just a primitive int out of an immutable list. Living in an immutable world means we can only create something new out of our input. What we want is to construct a new list, having car*2 as head and then the result of the recursive call to innerfunct. As usual, all branches of a function need to return some thing of the same type:
let multiply m =
let rec innerfunct = function
| [] ->
printfn "%A" m
[]
| car :: cdr ->
car*2 :: innerfunct cdr
innerfunct m
Knowing m is immutable, we can get rid of the printfn. If needed, we can put it outside of the function, anywhere we have access to the list. It will always print the same.
We finish by also making the reference to the list immutable and obtain a second (intermediate) solution:
let multiply m =
let rec innerfunct = function
| [] -> []
| car :: cdr -> car*2 :: innerfunct cdr
innerfunct m
let a = [1; 3; 4]
printfn "%A" a
let multiplied = multiply a
printfn "%A" multiplied
It might be nice to also multiply by different values (the function is called multiply after all and not double). Also, now that innerfunct is so small, we can make the names match the small scope (the smaller the scope, the shorter the names):
let multiply m xs =
let rec inner = function
| [] -> []
| x :: tail -> x*m :: inner tail
inner xs
Note that I put the factor first and the list last. This is similar to other List functions and allows to create pre-customized functions by using partial application:
let double = multiply 2
let doubled = double a
All that's left now is to make multiply tail-recursive:
let multiply m xs =
let rec inner acc = function
| [] -> acc
| x :: tail -> inner (x*m :: acc) tail
inner [] xs |> List.rev
So we end up having (for educational purposes) a hard-coded version of let multiply' m = List.map ((*) m)
F# is a 'single-pass' compiler, so you can expect any compilation error to have a cascading effect beneath the error. When you have a compilation error, focus on that single error. While you may have more errors in your code (you do), it may also be that subsequent errors are only consequences of the first error.
As the compiler says, car isn't mutable, so you can assign a value to it.
In Functional Programming, a map can easily be implemented as a recursive function:
// ('a -> 'b) -> 'a list -> 'b list
let rec map f = function
| [] -> []
| h::t -> f h :: map f t
This version, however, isn't tail-recursive, since it recursively calls map before it cons the head onto the tail.
You can normally refactor to a tail-recursive implementation by introducing an 'inner' implementation function that uses an accumulator for the result. Here's one way to do that:
// ('a -> 'b) -> 'a list -> 'b list
let map' f xs =
let rec mapImp f acc = function
| [] -> acc
| h::t -> mapImp f (acc # [f h]) t
mapImp f [] xs
Here, mapImp is the last operation to be invoked in the h::t case.
This implementation is a bit inefficient because it concatenates two lists (acc # [f h]) in each iteration. Depending on the size of the lists to map, it may be more efficient to cons the accumulator and then do a single reverse at the end:
// ('a -> 'b) -> 'a list -> 'b list
let map'' f xs =
let rec mapImp f acc = function
| [] -> acc
| h::t -> mapImp f (f h :: acc) t
mapImp f [] xs |> List.rev
In any case, however, the only reason to do all of this is for the exercise, because this function is already built-in.
In all cases, you can use map functions to multiply all elements in a list by two:
> let mdouble = List.map ((*) 2);;
val mdouble : (int list -> int list)
> mdouble [1..10];;
val it : int list = [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
Normally, though, I wouldn't even care to define such function explicitly. Instead, you use it inline:
> List.map ((*) 2) [1..10];;
val it : int list = [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
You can use all the above map function in the same way.
Symbols that you are creating in a match statement are not mutable, so when you are matching with (car::cdr) you cannot change their values.
Standard functional way would be to produce a new list with the computed values. For that you can write something like this:
let multiplyBy2 = List.map (fun x -> x * 2)
multiplyBy2 [1;2;3;4;5]
This is not tail recursive by itself (but List.map is).
If you really want to change values of the list, you could use an array instead. Then your function will not produce any new objects, just iterate through the array:
let multiplyArrayBy2 arr =
arr
|> Array.iteri (fun index value -> arr.[index] <- value * 2)
let someArray = [| 1; 2; 3; 4; 5 |]
multiplyArrayBy2 someArray

How do I append to a list in F# rather than prepend?

Prepending to a list in F# is somewhat annoying because once you're done you have to reverse it. Is there a way to build a list straight from start?
If you need to append elements to the end, you can use the type known as DList. There is an implementation available in FSharpX.
However, there is some runtime overhead associated with this (e.g. see the comments here) and so I think that building list by prepending and then reversing is generally going to be more efficient. It is also quite standard thing to do in functional programming - it may look a bit confusing at first, but it is a very common "design pattern" when implementing recursive functions that walk over lists, so I would not try to avoid it.
There is nothing wrong with prepending and reversing the list. You can use append (#) on a single-element list, but it is a code smell. A tolerable (tail-recursive) approach is:
let appendSingle xs x =
[ yield! xs
yield x ]
All the above solutions have O(n) execution time.
For your use case, you could keep a private ResizeArray to avoid the use of reverse. It is fine since mutability is hidden. Compare this function
let filter f l =
let rec loop acc l =
match l with
| [] -> List.rev acc
| x::xs when f x -> loop (x::acc) xs
| x::xs -> loop acc xs
loop [] l
with its more efficient counterpart
let filter f l =
let rec loop (acc : ResizeArray<_>) l =
match l with
| [] -> Seq.toList acc
| x::xs when f x ->
acc.Add(x)
loop acc xs
| x::xs -> loop acc xs
loop (ResizeArray()) l
Referring back to your original code, I think what you are looking for is to use List.foldBack rather than List.fold. Essentially, foldBack repeatedly applies the folder function starting from the end of the list rather than from the start of the list. It's not as efficient as fold but it's better to use foldBack and avoid reversing the list.
With foldBack, your accumulation function folder is applied to a list x0::x1::...::xlast as follows, where the initial argument to folder isinit:
folder x0 (folder x1 ( ... (folder xlast init) ... ) )
c.f. fold
folder (... (folder (folder init x0) x1) ...) xlast
There are some other answers to your original question that suggest alternative solutions, but sticking with your code, substituting foldBack for fold results in a first implementation
let chunkOrig items chunkSize =
let folder =
fun x (result, chunk) ->
if List.length chunk < chunkSize then
(result, x::chunk)
else
(chunk::result, [x])
let (a,b) = List.foldBack folder items ([], [])
b::a
Already this is a lot simpler, as all the list reversing has gone. And it seems to work.
> chunkOrig [1..10] 2;;
val it : int list list = [[1; 2]; [3; 4]; [5; 6]; [7; 8]; [9; 10]]
However when your list doesn't divide into equal chunks it goes wrong, because foldBack starts from the last element.
> chunkOrig [1..11] 2;;
val it : int list list = [[1]; [2; 3]; [4; 5]; [6; 7]; [8; 9]; [10; 11]]
What you need to do is parameterise your local function folder by the length remaining in the current chunk rather than by the chunk itself.
let chunk items chunkSize =
let folder =
fun x (result, lenLeft) ->
if lenLeft > 0 then
match result with
| [] -> ([[x]], lenLeft-1)
| r0::rtail -> ((x::r0)::rtail, lenLeft-1)
else
([x]::result, chunkSize-1)
let (result, lenLeft) = List.foldBack folder items ([], (List.length items) % chunkSize)
result
> chunk [1..10] 2;;
val it : int list list = [[1; 2]; [3; 4]; [5; 6]; [7; 8]; [9; 10]]
> chunk [1..11] 2;;
val it : int list list = [[1; 2]; [3; 4]; [5; 6]; [7; 8]; [9; 10]; [11]]
Append x to xs like this:
xs # [x]
Note that this is O(n).

Remove a single non-unique value from a sequence in F#

I have a sequence of integers representing dice in F#.
In the game in question, the player has a pool of dice and can choose to play one (governed by certain rules) and keep the rest.
If, for example, a player rolls a 6, 6 and a 4 and decides to play one the sixes, is there a simple way to return a sequence with only one 6 removed?
Seq.filter (fun x -> x != 6) dice
removes all of the sixes, not just one.
Non-trivial operations on sequences are painful to work with, since they don't support pattern matching. I think the simplest solution is as follows:
let filterFirst f s =
seq {
let filtered = ref false
for a in s do
if filtered.Value = false && f a then
filtered := true
else yield a
}
So long as the mutable implementation is hidden from the client, it's still functional style ;)
If you're going to store data I would use ResizeArray instead of a Sequence. It has a wealth of functions built in such as the function you asked about. It's simply called Remove. Note: ResizeArray is an abbreviation for the CLI type List.
let test = seq [1; 2; 6; 6; 1; 0]
let a = new ResizeArray<int>(test)
a.Remove 6 |> ignore
Seq.toList a |> printf "%A"
// output
> [1; 2; 6; 1; 0]
Other data type options could be Array
let removeOneFromArray v a =
let i = Array.findIndex ((=)v) a
Array.append a.[..(i-1)] a.[(i+1)..]
or List
let removeOneFromList v l =
let rec remove acc = function
| x::xs when x = v -> List.rev acc # xs
| x::xs -> remove (x::acc) xs
| [] -> acc
remove [] l
the below code will work for a list (so not any seq but it sounds like the sequence your using could be a List)
let rec removeOne value list =
match list with
| head::tail when head = value -> tail
| head::tail -> head::(removeOne value tail)
| _ -> [] //you might wanna fail here since it didn't find value in
//the list
EDIT: code updated based on correct comment below. Thanks P
EDIT: After reading a different answer I thought that a warning would be in order. Don't use the above code for infite sequences but since I guess your players don't have infite dice that should not be a problem but for but for completeness here's an implementation that would work for (almost) any
finite sequence
let rec removeOne value seq acc =
match seq.Any() with
| true when s.First() = value -> seq.Skip(1)
| true -> seq.First()::(removeOne value seq.Skip(1))
| _ -> List.rev acc //you might wanna fail here since it didn't find value in
//the list
However I recommend using the first solution which Im confident will perform better than the latter even if you have to turn a sequence into a list first (at least for small sequences or large sequences with the soughtfor value in the end)
I don't think there is any function that would allow you to directly represent the idea that you want to remove just the first element matching the specified criteria from the list (e.g. something like Seq.removeOne).
You can implement the function in a relatively readable way using Seq.fold (if the sequence of numbers is finite):
let removeOne f l =
Seq.fold (fun (removed, res) v ->
if removed then true, v::res
elif f v then true, res
else false, v::res) (false, []) l
|> snd |> List.rev
> removeOne (fun x -> x = 6) [ 1; 2; 6; 6; 1 ];
val it : int list = [1; 2; 6; 1]
The fold function keeps some state - in this case of type bool * list<'a>. The Boolean flag represents whether we already removed some element and the list is used to accumulate the result (which has to be reversed at the end of processing).
If you need to do this for (possibly) infinite seq<int>, then you'll need to use GetEnumerator directly and implement the code as a recursive sequence expression. This is a bit uglier and it would look like this:
let removeOne f (s:seq<_>) =
// Get enumerator of the input sequence
let en = s.GetEnumerator()
let rec loop() = seq {
// Move to the next element
if en.MoveNext() then
// Is this the element to skip?
if f en.Current then
// Yes - return all remaining elements without filtering
while en.MoveNext() do
yield en.Current
else
// No - return this element and continue looping
yield en.Current
yield! loop() }
loop()
You can try this:
let rec removeFirstOccurrence item screened items =
items |> function
| h::tail -> if h = item
then screened # tail
else tail |> removeFirstOccurrence item (screened # [h])
| _ -> []
Usage:
let updated = products |> removeFirstOccurrence product []

Resources