Search code examples
f#sequences

Lazy cartesian product of multiple sequences (sequence of sequences)


Can you suggest simpler and clearer way to write this function?

let cartesian_product sequences = 
    let step acc sequence = seq { 
        for x in acc do 
        for y in sequence do 
        yield Seq.append x [y] }
    Seq.fold step (Seq.singleton Seq.empty) sequences 

Solution

  • Less elegant, but (seems to be) faster solution:

    let cartesian_product2 sequences = 
        let step acc sequence = seq { 
            for x in acc do 
            for y in sequence do 
            yield seq { yield! x ; yield y } }
        Seq.fold step (Seq.singleton Seq.empty) sequences 
    

    ;

    > cartesian items |> Seq.length;;
    Real: 00:00:00.405, CPU: 00:00:00.405, GC gen0: 37, gen1: 1, gen2: 0
    val it : int = 1000000
    > cartesian_product2 items |> Seq.length;;
    Real: 00:00:00.228, CPU: 00:00:00.234, GC gen0: 18, gen1: 0, gen2: 0
    val it : int = 1000000