5 people like it.

Clumsy LoopBuilder

Clumsy LoopBuilder.It's mischievous trick.

Clumsy LoopBuilder

 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: 
type LoopBuilder () =
  let while' gd body = 
    (fun _ ->
      let b = gd() 
      if b then
        if Option.isSome (body ()) then Some ()
        else body () |> (fun _ -> None)
      else 
        Some ()) |> Seq.initInfinite
  member this.While(gd,body) =
      while' gd body |> Seq.tryFind (fun x -> Option.isSome x) |> ignore
  member this.For (s, f) =
      s |> Seq.tryFind (fun x -> Option.isSome (f x)) |> ignore
  member this.Zero () = None
  member this.Combine (a,b) = a |> function
    |Some x -> Some x
    |_ -> b()
  member this.Return (x) = x 
  member this.ReturnFrom (x) = Some x 
  member this.Bind (m,f) = m |> function
    |Some x -> f x |> Some
    |_ -> None
  member this.Delay f = f 
  member this.Run f = f ()

let break' = Some ()
let continue' = None
let loop = LoopBuilder ()

Example

 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: 
open System

printfn "%s" "----- for"
let hoge = 
  let x = ref "/(^o^)\"
  loop {for i in [1..10] do
          if i = 5 then
            printfn "%s" "five"
            do! continue' else 
          if i = 2 then
            printfn "%s" "two"
            do! continue' else
          printfn "%d" i
          if i = 7 then
            printfn "%s" "!!!"
            x := "\(^o^)/"
            return break'
            printfn "%d" i
          printfn "%s" "!" }
  !x
hoge |> printfn "%s"

printfn "%s" "----- while"
let fuga = 
  let x = ref "/(^o^)\"
  loop {let i = ref 0
        while !i < 6 do
          i := !i + 1
          if !i = 5 then
            printfn "%s" "five"
            do! continue' else
          if !i = 2 then
            printfn "%s" "two"
            do! continue' else
          printfn "%d" !i
          if !i = 7 then
            printfn "%s" "!!!"
            x := "\(^o^)/"
            return break'
            printfn "%d" !i
          printfn "%s" "!"}
  !x
fuga |> printfn "%s"
Console.ReadLine () |> ignore
Multiple items
type LoopBuilder =
  new : unit -> LoopBuilder
  member Bind : m:'c option * f:('c -> 'd) -> 'd option
  member Combine : a:'g option * b:(unit -> 'g option) -> 'g option
  member Delay : f:'b -> 'b
  member For : s:seq<'i> * f:('i -> 'j option) -> unit
  member Return : x:'f -> 'f
  member ReturnFrom : x:'e -> 'e option
  member Run : f:(unit -> 'a) -> 'a
  member While : gd:(unit -> bool) * body:(unit -> 'k option) -> unit
  member Zero : unit -> 'h option

Full name: Script.LoopBuilder

--------------------
new : unit -> LoopBuilder
val while' : ((unit -> bool) -> (unit -> 'a option) -> seq<unit option>)
val gd : (unit -> bool)
val body : (unit -> 'a option)
val b : bool
module Option

from Microsoft.FSharp.Core
val isSome : option:'T option -> bool

Full name: Microsoft.FSharp.Core.Option.isSome
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
module Seq

from Microsoft.FSharp.Collections
val initInfinite : initializer:(int -> 'T) -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.initInfinite
val this : LoopBuilder
member LoopBuilder.While : gd:(unit -> bool) * body:(unit -> 'k option) -> unit

Full name: Script.LoopBuilder.While
val body : (unit -> 'k option)
val tryFind : predicate:('T -> bool) -> source:seq<'T> -> 'T option

Full name: Microsoft.FSharp.Collections.Seq.tryFind
val x : unit option
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
member LoopBuilder.For : s:seq<'i> * f:('i -> 'j option) -> unit

Full name: Script.LoopBuilder.For
val s : seq<'i>
val f : ('i -> 'j option)
val x : 'i
member LoopBuilder.Zero : unit -> 'h option

Full name: Script.LoopBuilder.Zero
member LoopBuilder.Combine : a:'g option * b:(unit -> 'g option) -> 'g option

Full name: Script.LoopBuilder.Combine
val a : 'g option
val b : (unit -> 'g option)
val x : 'g
member LoopBuilder.Return : x:'f -> 'f

Full name: Script.LoopBuilder.Return
val x : 'f
member LoopBuilder.ReturnFrom : x:'e -> 'e option

Full name: Script.LoopBuilder.ReturnFrom
val x : 'e
member LoopBuilder.Bind : m:'c option * f:('c -> 'd) -> 'd option

Full name: Script.LoopBuilder.Bind
val m : 'c option
val f : ('c -> 'd)
val x : 'c
member LoopBuilder.Delay : f:'b -> 'b

Full name: Script.LoopBuilder.Delay
val f : 'b
member LoopBuilder.Run : f:(unit -> 'a) -> 'a

Full name: Script.LoopBuilder.Run
val f : (unit -> 'a)
val break' : unit option

Full name: Script.break'
val continue' : 'a option

Full name: Script.continue'
val loop : LoopBuilder

Full name: Script.loop
namespace System
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val hoge : string

Full name: Script.hoge
val x : string ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val i : int
val fuga : string

Full name: Script.fuga
val i : int ref
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

Link:http://fssnip.net/7t
Posted:6 years ago
Author:zecl
Tags: computation builder , break , continue