I come from SML background and feel quite comfortable with high-order functions. But I don\'t really get the idea of list comprehension. Is there any situation where list co
Choosing between comprehensions and higher-order functions is mostly a matter of style. I think that comprehensions are sometimes more readable, but that's just a personal preference. Note that the cartesian
function could be written more elegantly like this:
let rec cartesian = function
| [] -> [[]]
| L::Ls ->
[ for C in cartesian Ls do for x in L do yield x::C ]
The interesting case is when writing recursive functions. If you use sequences (and sequence comprehensions), they remove some unnecessary allocation of temporary lists and if you use yield!
in a tail-call position, you can also avoid stack overflow exceptions:
let rec nums n =
if n = 100000 then []
else n::(nums (n+1))
// throws StackOverflowException
nums 0
let rec nums n = seq {
if n < 100000 then
yield n
yield! nums (n+1) }
// works just fine
nums 0 |> List.ofSeq
This is quite an interesting pattern, because it cannot be written in the same way using lists. When using lists, you cannot return some element and then make a recursive call, because it corresponds to n::(nums ...)
, which is not tail-recursive.