11 people like it.
Like the snippet!
LazyBuilder
I made LazyBuilder. The synthesis of the lazy function is troublesome. When the call of the Force() method increases, it is ugly. This solves the problem.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
|
module Lazy =
type LazyBuilder () =
let force (x : Lazy<'T>) = x |> function | Lazy x -> x
/// bind
let (>>=) (x:Lazy<'a>) (f:('a -> Lazy<'a>)) : Lazy<'a> =
lazy (x |> force |> f |> force)
/// zero
let lazyzero = Seq.empty
member this.Bind(x, f) = x >>= f
member this.Return (x) = lazy x
member this.ReturnFrom (x) = x
member this.Zero() = lazyzero
member this.Delay f = f()
member this.Combine (a,b) =
Seq.append a b
member this.Combine (a,b) =
Seq.append (Seq.singleton a) b
member this.Combine (a,b) =
Seq.append a (Seq.singleton b)
member this.Combine (Lazy(a), Lazy(b)) =
lazy Seq.append a b
member this.Combine (a:Lazy<'T>, b:Lazy<seq<'T>>) =
(a,b) |> function | (Lazy x, Lazy y) -> lazy Seq.append (Seq.singleton x) y
member this.Combine (a:Lazy<seq<'T>>, Lazy(b)) =
a |> function | Lazy x -> lazy Seq.append x (Seq.singleton b)
member this.Combine (a:Lazy<seq<'T>>, b:seq<Lazy<'T>>) =
let notlazy (xs:seq<Lazy<'T>>) = xs |> Seq.map (fun (Lazy(a)) -> a)
a |> function | Lazy x -> lazy Seq.append x (notlazy b)
member this.Combine (a:seq<Lazy<'T>>, b:Lazy<seq<'T>>) =
let notlazy (xs:seq<Lazy<'T>>) = xs |> Seq.map (fun (Lazy(a)) -> a)
b |> function | Lazy x -> lazy Seq.append (notlazy a) x
member this.For (s,f) =
s |> Seq.map f
member this.Yield x = lazy x
member this.YieldFrom x = x
member this.Run (x:Lazy<'T>) = x
member this.Run (xs:seq<Lazy<unit>>) =
xs |> Seq.reduce (fun a b -> this.Bind(a, fun _ -> b))
member this.Run (xs:seq<Lazy<'T>>) =
xs |> Seq.map (fun (Lazy(a)) -> a) |> fun x -> lazy x
let lazyz = LazyBuilder ()
let lifM f (Lazy(a)) = lazy f a
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
|
open System
open Lazy
let result =
lazyz { let! a = lazy ("Hello,")
let! b = lazy ("World!")
return a + b}
result.Force() |> (printfn "%s") |> ignore
let lazyp n = lazy (printfn "%d" n)
let result2 =
let a =
lazyz {
yield! lazyp 2
()}
lazyz {
yield! lazyp 0
yield! lazyp 1
yield! a
for i in 3..5 do
yield! lazyp i
yield! lazyp 6
yield! lazyz {
yield! lazyp 7
yield! lazyp 8
()}
for i in 9..10 do
yield! lazyp i
yield! seq {for n in [11..15] -> lazyp n}
yield! lazyz {
yield! lazyp 16
yield! lazyp 17
()}
yield! lazyz {
yield! lazyp 18
yield! lazyp 19
()}
yield! lazyp 20
() }
result2.Force()
Console.ReadLine () |> ignore
|
Multiple items
active recognizer Lazy: Lazy<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.( |Lazy| )
--------------------
type Lazy<'T> = System.Lazy<'T>
Full name: Microsoft.FSharp.Control.Lazy<_>
Multiple items
type LazyBuilder =
new : unit -> LazyBuilder
member Bind : x:Lazy<'o> * f:('o -> Lazy<'o>) -> Lazy<'o>
member Combine : a:seq<'j> * b:seq<'j> -> seq<'j>
member Combine : a:'i * b:seq<'i> -> seq<'i>
member Combine : a:seq<'h> * b:'h -> seq<'h>
member Combine : Lazy<#seq<'f>> * Lazy<#seq<'f>> -> Lazy<seq<'f>>
member Combine : a:Lazy<'T> * b:Lazy<seq<'T>> -> Lazy<seq<'T>>
member Combine : a:Lazy<seq<'T>> * Lazy<'T> -> Lazy<seq<'T>>
member Combine : a:Lazy<seq<'T>> * b:seq<Lazy<'T>> -> Lazy<seq<'T>>
member Combine : a:seq<Lazy<'T>> * b:Lazy<seq<'T>> -> Lazy<seq<'T>>
...
Full name: Script.Lazy.LazyBuilder
--------------------
new : unit -> LazyBuilder
val force : (Lazy<'T> -> 'T)
val x : Lazy<'T>
val x : 'T
val x : Lazy<'a>
val f : ('a -> Lazy<'a>)
val lazyzero : seq<'a>
zero
module Seq
from Microsoft.FSharp.Collections
val empty<'T> : seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.empty
val this : LazyBuilder
member LazyBuilder.Bind : x:Lazy<'o> * f:('o -> Lazy<'o>) -> Lazy<'o>
Full name: Script.Lazy.LazyBuilder.Bind
val x : Lazy<'o>
val f : ('o -> Lazy<'o>)
member LazyBuilder.Return : x:'n -> Lazy<'n>
Full name: Script.Lazy.LazyBuilder.Return
val x : 'n
member LazyBuilder.ReturnFrom : x:'m -> 'm
Full name: Script.Lazy.LazyBuilder.ReturnFrom
val x : 'm
member LazyBuilder.Zero : unit -> seq<'l>
Full name: Script.Lazy.LazyBuilder.Zero
member LazyBuilder.Delay : f:(unit -> 'k) -> 'k
Full name: Script.Lazy.LazyBuilder.Delay
val f : (unit -> 'k)
member LazyBuilder.Combine : a:seq<'j> * b:seq<'j> -> seq<'j>
Full name: Script.Lazy.LazyBuilder.Combine
val a : seq<'j>
val b : seq<'j>
val append : source1:seq<'T> -> source2:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.append
member LazyBuilder.Combine : a:'i * b:seq<'i> -> seq<'i>
Full name: Script.Lazy.LazyBuilder.Combine
val a : 'i
val b : seq<'i>
val singleton : value:'T -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.singleton
member LazyBuilder.Combine : a:seq<'h> * b:'h -> seq<'h>
Full name: Script.Lazy.LazyBuilder.Combine
val a : seq<'h>
val b : 'h
member LazyBuilder.Combine : Lazy<#seq<'f>> * Lazy<#seq<'f>> -> Lazy<seq<'f>>
Full name: Script.Lazy.LazyBuilder.Combine
val a : #seq<'f>
val b : #seq<'f>
member LazyBuilder.Combine : a:Lazy<'T> * b:Lazy<seq<'T>> -> Lazy<seq<'T>>
Full name: Script.Lazy.LazyBuilder.Combine
val a : Lazy<'T>
val b : Lazy<seq<'T>>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val y : seq<'T>
member LazyBuilder.Combine : a:Lazy<seq<'T>> * Lazy<'T> -> Lazy<seq<'T>>
Full name: Script.Lazy.LazyBuilder.Combine
val a : Lazy<seq<'T>>
val b : 'T
val x : seq<'T>
member LazyBuilder.Combine : a:Lazy<seq<'T>> * b:seq<Lazy<'T>> -> Lazy<seq<'T>>
Full name: Script.Lazy.LazyBuilder.Combine
val b : seq<Lazy<'T>>
val notlazy : (seq<Lazy<'T>> -> seq<'T>)
val xs : seq<Lazy<'T>>
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
val a : 'T
member LazyBuilder.Combine : a:seq<Lazy<'T>> * b:Lazy<seq<'T>> -> Lazy<seq<'T>>
Full name: Script.Lazy.LazyBuilder.Combine
val a : seq<Lazy<'T>>
member LazyBuilder.For : s:seq<'c> * f:('c -> 'd) -> seq<'d>
Full name: Script.Lazy.LazyBuilder.For
val s : seq<'c>
val f : ('c -> 'd)
member LazyBuilder.Yield : x:'b -> Lazy<'b>
Full name: Script.Lazy.LazyBuilder.Yield
val x : 'b
member LazyBuilder.YieldFrom : x:'a -> 'a
Full name: Script.Lazy.LazyBuilder.YieldFrom
val x : 'a
member LazyBuilder.Run : x:Lazy<'T> -> Lazy<'T>
Full name: Script.Lazy.LazyBuilder.Run
member LazyBuilder.Run : xs:seq<Lazy<unit>> -> Lazy<unit>
Full name: Script.Lazy.LazyBuilder.Run
val xs : seq<Lazy<unit>>
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
val reduce : reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T
Full name: Microsoft.FSharp.Collections.Seq.reduce
val a : Lazy<unit>
val b : Lazy<unit>
member LazyBuilder.Bind : x:Lazy<'o> * f:('o -> Lazy<'o>) -> Lazy<'o>
member LazyBuilder.Run : xs:seq<Lazy<'T>> -> Lazy<seq<'T>>
Full name: Script.Lazy.LazyBuilder.Run
val lazyz : LazyBuilder
Full name: Script.Lazy.lazyz
val lifM : f:('a -> 'b) -> Lazy<'a> -> Lazy<'b>
Full name: Script.Lazy.lifM
val f : ('a -> 'b)
val a : 'a
namespace System
Multiple items
active recognizer Lazy: Lazy<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.( |Lazy| )
--------------------
type Lazy<'T> =
new : unit -> Lazy<'T> + 5 overloads
member IsValueCreated : bool
member ToString : unit -> string
member Value : 'T
Full name: System.Lazy<_>
--------------------
Lazy() : unit
Lazy(valueFactory: Func<'T>) : unit
Lazy(isThreadSafe: bool) : unit
Lazy(mode: Threading.LazyThreadSafetyMode) : unit
Lazy(valueFactory: Func<'T>, isThreadSafe: bool) : unit
Lazy(valueFactory: Func<'T>, mode: Threading.LazyThreadSafetyMode) : unit
val result : Lazy<string>
Full name: Script.result
val a : string
val b : string
member Lazy.Force : unit -> 'T
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
val lazyp : n:int -> Lazy<unit>
Full name: Script.lazyp
val n : int
val result2 : Lazy<unit>
Full name: Script.result2
val i : int
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
type Console =
static member BackgroundColor : ConsoleColor with get, set
static member Beep : unit -> unit + 1 overload
static member BufferHeight : int with get, set
static member BufferWidth : int with get, set
static member CapsLock : bool
static member Clear : unit -> unit
static member CursorLeft : int with get, set
static member CursorSize : int with get, set
static member CursorTop : int with get, set
static member CursorVisible : bool with get, set
...
Full name: System.Console
Console.ReadLine() : string
More information