Sunday, 20 June 2010

Subsequences of a seq<'a>

let cons x xs = seq { yield x
                      yield! xs }

let (|Empty|Cons|) xs : Choice<Unit, 'a * seq<'a>> =
     if (Seq.isEmpty xs) then
        Empty
      else
        Cons(Seq.head xs, Seq.skip 1 xs)

let rec subseq xs =
    match xs with
    | Empty -> seq[seq[]]
    | Cons(x,xs) -> let subseq = subseq xs
                    Seq.append (Seq.map (cons x) subseq) subseq

open System
open FsCheck

type MyGenerators =
    static member Seq() =
        let fsList = Arb.Default.FsList()
        {new Arbitrary<seq<'a>>() with
            override x.Generator =
                Gen.resize 10 (Gen.map (List.toSeq) (fsList.Generator))
            override x.Shrinker t =
                Seq.map (List.toSeq) (fsList.Shrinker(Seq.toList t)) }

ignore (Arb.register<MyGenerators>())

Check.Quick (fun xs -> (Seq.length (subseq xs) =
                       int (Math.Pow(2.0, (float (Seq.length xs))))))

1 comment:

J-C said...

Beware of Seq.skip that causes space and time leaks