I understand and wrote a typical power set function in F# (similar to the Algorithms section in Wikipedia)
Later I found this implementation of powerset which seems nice and compact, expect that I do not understand it.
let rec powerset = function
| [] -> [[]]
| h::t -> List.fold (fun xs t -> (h::t)::t::xs) [] (powerset t);
I broke this down to a 1 step non-recursive function to find the powerset of [1;2] and hardcoded the value of power set of 2 at the end [[2]; []]
let right = function
| [] -> [[]]
| h::t -> List.fold (fun acc t -> (h::t)::t::acc) [] [[2]; []];
The output is [[1]; []; [1; 2]; [2]]
which is correct.
However I was expecting List.Fold to output [[1; 2]; []; [1; 2]; [2]]
.
Since I was not certain about the 't', I modified the variable names, and I did get what I had expected. Of course this is not the correct powerset of [1;2].
let wrong = function
| [] -> [[]]
| h::t -> List.fold (fun acc data -> (h::t)::data::acc) [] [[2]; []];
For me 't' (the one withing fun and not the h::t) is simply a name for the second argument to 'fun' but that is obviously not the case. So what is the difference in the "right" and "wrong" F# functions I have written ? And what exactly does 't' here refer to ?
Thank you ! (I am new to F#)
In your "right" example, t
is originally the name of the value bound in the pattern match, but it is hidden by the parameter t
in the lambda expression passed to List.fold
. Whereas in your "wrong" example, t
is captured as a closure in the lambda expression. I think maybe you don't intend this capture, instead you want:
//now it works as you expect, replaced "t" with "data" in your lambda expression.
let wrong = function
| [] -> [[]]
| h::t -> List.fold (fun acc data -> (h::data)::data::acc) [] [[2]; []];