open System.Collections.Generic
type Imperative<'T> = unit -> option<'T>
type ImperativeBuilder() =
member x.Return(v) : Imperative<_> =
member x.Zero() = (fun () -> None)
member x.Delay(f:unit -> Imperative<_>) =
member x.Combine(a, b) = (fun () ->
| None -> failwith "nothing returned!"
type ImperativeBuilder with
member x.For(inp:seq<_>, f) =
let rec loop(en:IEnumerator<_>) =
if not(en.MoveNext()) then x.Zero() else
x.Combine(f(en.Current), x.Delay(fun () -> loop(en)))
loop(inp.GetEnumerator())
member x.While(gd, body) =
if not(gd()) then x.Zero() else
x.Combine(body, x.Delay(fun () -> loop()))
let imperative = ImperativeBuilder()
let exists f inp = imperative {
let res = [ 1 .. 10 ] |> exists (fun v -> v % 3 = 0)