Search code examples
listf#pattern-matchingsequencelazy-evaluation

Is it possible to match with decomposed sequences in F#?


I seem to remember an older version of F# allowing structural decomposition when matching sequences just like lists. Is there a way to use the list syntax while keeping the sequence lazy? I'm hoping to avoid a lot of calls to Seq.head and Seq.skip 1.

I'm hoping for something like:

let decomposable (xs:seq<'a>) =
   match xs with
   | h :: t -> true
   | _ -> false
seq{ 1..100 } |> decomposable

But this only handles lists and gives a type error when using sequences. When using List.of_seq, it seems to evaluate all the elements in the sequence, even if it is infinite.


Solution

  • If you use the LazyList type in the PowerPack, it has Active Patterns called LazyList.Nil and LazyList.Cons that are great for this.

    The seq/IEnumerable type is not particulaly amenable to pattern matching; I'd highly recommend LazyList for this. (See also Why is using a sequence so much slower than using a list in this example.)

    let s = seq { 1..100 }
    let ll = LazyList.ofSeq s
    match ll with
    | LazyList.Nil -> printfn "empty"
    | LazyList.Cons(h,t) -> printfn "head: %d" h