type M<'T> = Tree -> Tree * 'T and Tree = | Leaf | Branch of Tree * Tree type MBuilder () = member __.Return(t : 'T) : M<'T> = fun s -> s,t member __.ReturnFrom(m : M<'T>) = m member __.Bind(m : M<'T>, g : 'T -> M<'S>) : M<'S> = fun mt -> let mt',t = m Leaf in g t (Branch(mt, mt')) let run (m : M<_>) = fst (m Leaf) let m = new MBuilder() // 1. left unit m { let! x = m { return 1 } return! m { return x + 1 } } |> run m { let x = 1 return! m { return x + 1 } } |> run // 2. right unit m { return 1 } |> run m { let! x = m { return 1 } return x } |> run // 3. associativity m { let! x = m { return 1 } let! y = m { return x + 1 } return y } |> run m { let! y = m { let! x = m { return 1 } return! m { return x + 1 } } return y } |> run