I benchmarked the function Juliet linked to:
let items = List.init 6 (fun _ -> [0..9])
cart1 items |> Seq.length |> ignore
Real: 00:00:03.324, CPU: 00:00:03.322, GC gen0: 80, gen1: 0, gen2: 0
and a slightly modified (to make it an apples-to-apples comparison) version of yours:
let cartesian items =
items |> Seq.fold (fun acc s ->
seq { for x in acc do for y in s do yield x @ [y] }) (Seq.singleton [])
cartesian items |> Seq.length |> ignore
Real: 00:00:00.763, CPU: 00:00:00.780, GC gen0: 37, gen1: 2, gen2: 1
Yours is significantly faster (and causes fewer GCs). Looks to me that what you have is good.