This one adds overloads to Bind, which show how both multiple types of let! bindings as well as do! bindings can be produced. It prints a trace of the calls and returns to the console, illustrating the descend an return behavior.
Below are the output and the code. As always, it is presented "as-is" and without warranty or implied fitness of any kind; use at your own risk.
/// Sample do!,let!,return! binder.
type Binder () =
/// For indent to list level.
let rec spaces spc = function
| [] -> spc
| h::t -> spaces (" "+spc) t
/// let! binding (first use).
member this.Bind (s:string,
f:string list->string list) =
printfn "Entering let! %s,[]" s
let rtn = List.tail (f [s])
printfn "%sLeaving let! %s,%A" (spaces "" rtn) s rtn
rtn
/// let! binding (nth use).
member this.Bind ((s,sl):string*(string list),
f:string list->string list) =
printfn "%sEntering let! %s,%A" (spaces "" sl) s sl
let rtn = List.tail (f (s::sl))
printfn "%sLeaving let! %s,%A" (spaces "" rtn) s rtn
rtn
/// do! binding.
member this.Bind ((s,sl):string*(string list),
f:unit->string list) =
printfn "%sEntering do! %s,%A" (spaces "" sl) s sl
let rtn = f()
printfn "%sLeaving do! %s,%A" (spaces "" rtn) s rtn
rtn
/// return.
member this.Return (a:string list) =
printfn "%sReturn %A" (spaces "" a) a
a
// Test.
let result = Binder () {
let! x = "A"
let! x = "B",x
do! "B0",x
let! x = "C",x
return x }
printfn "Your breakpoint here."
p.s. For the spaces function you could also use something like:
new string(' ',sl.Length*2)
No comments:
Post a Comment