Skip to content

Instantly share code, notes, and snippets.

@Szer
Last active June 17, 2020 23:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Szer/acc467571a0b013a0efe70c76cf5f149 to your computer and use it in GitHub Desktop.
Save Szer/acc467571a0b013a0efe70c76cf5f149 to your computer and use it in GitHub Desktop.
Pattern matching for all sequences
open System
[<RequireQualifiedAccess>]
module Seq =
let inline (|Nil|Cons|) (someSeq: seq<_>) =
let mutable enum = Unchecked.defaultof<IEnumerator<_>>
let mutable shouldDispose = true
try
enum <- someSeq.GetEnumerator()
if enum.MoveNext() then
let head = enum.Current
shouldDispose <- false
let rest = seq {
use localEnum = enum
while localEnum.MoveNext() do
yield localEnum.Current
}
Cons(head, rest)
else
Nil
finally
if shouldDispose && not(isNull enum) then
(enum :> IDisposable).Dispose()
@ForNeVeR
Copy link

Please ensure these samples properly work (finally should always execute):

let ex1 = seq {
  try
    throw Exception()
  finally
    printfn "Should always print this"
}
let ex2 = seq {
  try
    return! [||]
  finally 
    printfn "Should always print this"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment