11 people like it.

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.

LazyBuilder

 ``` 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>) = (a,b) |> function | (Lazy x, Lazy y) -> lazy Seq.append (Seq.singleton x) y member this.Combine (a:Lazy>, Lazy(b)) = a |> function | Lazy x -> lazy Seq.append x (Seq.singleton b) member this.Combine (a:Lazy>, b:seq>) = let notlazy (xs:seq>) = xs |> Seq.map (fun (Lazy(a)) -> a) a |> function | Lazy x -> lazy Seq.append x (notlazy b) member this.Combine (a:seq>, b:Lazy>) = let notlazy (xs:seq>) = 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>) = xs |> Seq.reduce (fun a b -> this.Bind(a, fun _ -> b)) member this.Run (xs:seq>) = xs |> Seq.map (fun (Lazy(a)) -> a) |> fun x -> lazy x let lazyz = LazyBuilder () let lifM f (Lazy(a)) = lazy f a ``````

Sample

 ``` 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(valueFactory: Func<'T>, isThreadSafe: bool) : 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