I am trying to get my head around defining a stateful builder and I can't get around some compiler errors
type Movement =
| Left of int
| Right of int
type MovementState = Movement list -> Movement list
type MovementBuilder () =
member x.Zero () : MovementState = id
member __.Return x : MovementState = id
member __.Bind(m: MovementState, f: MovementState ) = fun v -> f (m v)
[<CustomOperation("left", MaintainsVariableSpaceUsingBind = true)>]
member x.Left(ms, value) = x.Bind(ms, fun xs -> xs @ [Left value])
[<CustomOperation("right", MaintainsVariableSpaceUsingBind = true)>]
member x.Right(ms, value) = x.Bind(ms, fun xs -> xs @ [Right value])
let movement = MovementBuilder()
[]
|> movement {
left 10
right 20
}
|> printfn "list %A"
//prints [Left 10; Right 20]
However now I want introduce a let!
or yield
so I can add additional items without going via the defined CustomOperations
so that for example I can so the following
[]
|> movement {
left 10
let! _ = (fun xs -> xs @ [Right 99])
//I also tried naming the value
//let! x = (fun xs -> xs @ [Right 99])
//I also tried wrapping it into another function ...
//let! x = fun () -> (fun xs -> xs @ [Right 99])
right 20
}
|> printfn "list %A"
//Should print [Left 10; Right 99; Right 20]
Any help is greatly appreciated.
Bonus Karma will be send for explaining how the compiler rewrites that into a series of Bind
s
Thx