Skip to content

Instantly share code, notes, and snippets.

@Lakret
Created January 25, 2012 21:00
Show Gist options
  • Save Lakret/1678686 to your computer and use it in GitHub Desktop.
Save Lakret/1678686 to your computer and use it in GitHub Desktop.
Stack expression builder declaration and example of usage
open System.Collections.Generic
type StackComprehensionsBuilder() =
member this.Yield x = new Stack<_>([x])
member this.YieldFrom (s : 'a seq) = new Stack<_>(s)
//s2 : unit -> Stack<_> — из-за Delay
member this.Combine(s1 : Stack<_>, s2 : unit -> Stack<_>) =
let s2' = s2().ToArray() |> Array.rev
for elem in s2' do
s1.Push elem
s1
member this.For(coll : 'a seq, body : ('a -> Stack<_>)) =
let s = new Stack<_>()
for elem in coll do
for generated in (body elem) do
s.Push generated
s
//Delay позволяет нам вычислять тело ф-ции много раз
//http://stackoverflow.com/questions/4577050/what-is-the-role-of-while-loops-in-computation-expressions-in-f
member this.While(p : unit -> bool, body : unit -> Stack<_>) =
if p() then
this.Combine(body(), fun () -> this.While(p, body))
else
new Stack<_>()
member this.Zero () = new Stack<_>()
member this.TryWith(tryBlock : unit -> Stack<_>, handler : exn -> Stack<_>) =
try tryBlock() with | e -> handler e
member this.TryFinally(tryBlock : unit -> Stack<_>, finalizer : unit -> unit) =
try tryBlock() finally finalizer()
member this.Delay f = f
//вычисляем всё в конце
member x.Run f = f()
let stack = new StackComprehensionsBuilder()
let s =
stack {
for x in 0..10 -> x
yield 12
yield 13
let x = 50
yield! [x..60]
if 1 < 0 then
yield 111
let x = ref 5
while !x > 0 do
yield !x
x := !x - 1
try
yield 1 / 0
with
| _ -> yield 0
try
yield 1
finally
printfn "Slow!"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment