0 people like it.

Cartesian product in sequence expression

Sequence expression which deals with cartesian product of sequences with for ... do expression. It replaces nested for .. do expression to single one.

implementation

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
open System
type SeqBuilder () =    
  member __.For(m,f) = Seq.collect f m
  member __.For((m1,m2):#seq<_>*_, f) =
     __.For(m1,fun x1 -> Seq.collect(fun x2 -> f(x1,x2)) m2) 
  member __.For((m1,m2,m3):_*_*_, f) = 
    __.For((m1,m2),fun(x1,x2)-> Seq.collect(fun x3 -> f(x1,x2,x3)) m3)
  member __.For((m1,m2,m3,m4):_*_*_*_, f) = 
    __.For((m1,m2,m3),fun(x1,x2,x3)-> Seq.collect(fun x4 -> f(x1,x2,x3,x4)) m4)
  
  member __.Yield x = Seq.singleton x
  member __.YieldFrom x = x
  member __.Zero() = Seq.empty
  member __.Delay f = f
  member __.Run f = f ()
  member __.Combine(m1,m2) = Seq.append m1 (m2())
  member __.While(guard, body:_->_ seq) =
    seq { while guard () do yield! body () }

let seq' = SeqBuilder ()

usage

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
seq' {                       
yield "before nested loop..\r\n"
for i,j,k,l in [0..1],[0..1],[0..1],[0..1] do
  let m = ref 0
  while !m < 2 do
    yield! [ for n in 0..1 -> sprintf "%2d " (i*32 + j*16 + k*8 + l*4 + !m*2 + n) ]
    incr m
  if l = 1 then yield "\r\n"
} |> Seq.iter (printf "%s")

result

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
//before nested loop..
// 0  1  2  3  4  5  6  7 
// 8  9 10 11 12 13 14 15 
//16 17 18 19 20 21 22 23 
//24 25 26 27 28 29 30 31 
//32 33 34 35 36 37 38 39 
//40 41 42 43 44 45 46 47 
//48 49 50 51 52 53 54 55 
//56 57 58 59 60 61 62 63 
namespace System
Multiple items
type SeqBuilder =
  new : unit -> SeqBuilder
  member Combine : m1:seq<'b> * m2:(unit -> #seq<'b>) -> seq<'b>
  member Delay : f:'e -> 'e
  member For : m:seq<'a13> * f:('a13 -> #seq<'a15>) -> seq<'a15>
  member For : (#seq<'a8> * #seq<'a10>) * f:('a8 * 'a10 -> #seq<'a12>) -> seq<'a12>
  member For : (#seq<'t> * #seq<'a2> * #seq<'a4>) * f:('t * 'a2 * 'a4 -> #seq<'a6>) -> seq<'a6>
  member For : (#seq<'j> * #seq<'l> * #seq<'n> * #seq<'p>) * f:('j * 'l * 'n * 'p -> #seq<'r>) -> seq<'r>
  member Run : f:(unit -> 'd) -> 'd
  member While : guard:(unit -> bool) * body:(unit -> seq<'a>) -> seq<'a>
  member Yield : x:'h -> seq<'h>
  ...

Full name: Script.SeqBuilder

--------------------
new : unit -> SeqBuilder
member SeqBuilder.For : m:seq<'a13> * f:('a13 -> #seq<'a15>) -> seq<'a15>

Full name: Script.SeqBuilder.For
val m : seq<'a13>
val f : ('a13 -> #seq<'a15>)
module Seq

from Microsoft.FSharp.Collections
val collect : mapping:('T -> #seq<'U>) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.collect
val __ : SeqBuilder
member SeqBuilder.For : (#seq<'a8> * #seq<'a10>) * f:('a8 * 'a10 -> #seq<'a12>) -> seq<'a12>

Full name: Script.SeqBuilder.For
val m1 : #seq<'a8>
val m2 : #seq<'a10>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val f : ('a8 * 'a10 -> #seq<'a12>)
member SeqBuilder.For : m:seq<'a13> * f:('a13 -> #seq<'a15>) -> seq<'a15>
member SeqBuilder.For : (#seq<'a8> * #seq<'a10>) * f:('a8 * 'a10 -> #seq<'a12>) -> seq<'a12>
member SeqBuilder.For : (#seq<'t> * #seq<'a2> * #seq<'a4>) * f:('t * 'a2 * 'a4 -> #seq<'a6>) -> seq<'a6>
member SeqBuilder.For : (#seq<'j> * #seq<'l> * #seq<'n> * #seq<'p>) * f:('j * 'l * 'n * 'p -> #seq<'r>) -> seq<'r>
val x1 : 'a8
val x2 : 'a10
member SeqBuilder.For : (#seq<'t> * #seq<'a2> * #seq<'a4>) * f:('t * 'a2 * 'a4 -> #seq<'a6>) -> seq<'a6>

Full name: Script.SeqBuilder.For
val m1 : #seq<'t>
val m2 : #seq<'a2>
val m3 : #seq<'a4>
val f : ('t * 'a2 * 'a4 -> #seq<'a6>)
val x1 : 't
val x2 : 'a2
val x3 : 'a4
member SeqBuilder.For : (#seq<'j> * #seq<'l> * #seq<'n> * #seq<'p>) * f:('j * 'l * 'n * 'p -> #seq<'r>) -> seq<'r>

Full name: Script.SeqBuilder.For
val m1 : #seq<'j>
val m2 : #seq<'l>
val m3 : #seq<'n>
val m4 : #seq<'p>
val f : ('j * 'l * 'n * 'p -> #seq<'r>)
val x1 : 'j
val x2 : 'l
val x3 : 'n
val x4 : 'p
member SeqBuilder.Yield : x:'h -> seq<'h>

Full name: Script.SeqBuilder.Yield
val x : 'h
val singleton : value:'T -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.singleton
member SeqBuilder.YieldFrom : x:'g -> 'g

Full name: Script.SeqBuilder.YieldFrom
val x : 'g
member SeqBuilder.Zero : unit -> seq<'f>

Full name: Script.SeqBuilder.Zero
val empty<'T> : seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.empty
member SeqBuilder.Delay : f:'e -> 'e

Full name: Script.SeqBuilder.Delay
val f : 'e
member SeqBuilder.Run : f:(unit -> 'd) -> 'd

Full name: Script.SeqBuilder.Run
val f : (unit -> 'd)
member SeqBuilder.Combine : m1:seq<'b> * m2:(unit -> #seq<'b>) -> seq<'b>

Full name: Script.SeqBuilder.Combine
val m1 : seq<'b>
val m2 : (unit -> #seq<'b>)
val append : source1:seq<'T> -> source2:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.append
member SeqBuilder.While : guard:(unit -> bool) * body:(unit -> seq<'a>) -> seq<'a>

Full name: Script.SeqBuilder.While
val guard : (unit -> bool)
val body : (unit -> seq<'a>)
val seq' : SeqBuilder

Full name: Script.seq'
val i : int
val j : int
val k : int
val l : int
val m : int ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val n : int
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val incr : cell:int ref -> unit

Full name: Microsoft.FSharp.Core.Operators.incr
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
val printf : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printf

More information

Link:http://fssnip.net/jC
Posted:10 years ago
Author:nagat01
Tags: sequence , computation expression