open System type StringBuilder = B of (Text.StringBuilder -> unit) let build (B f) = let b = new Text.StringBuilder() do f b b.ToString () type StringBuilderM () = let (!) = function B f -> f member __.Yield (txt : string) = B(fun b -> b.Append txt |> ignore) member __.Yield (c : char) = B(fun b -> b.Append c |> ignore) // member __.Yield (o : obj) = B(fun b -> b.Append o |> ignore) member __.YieldFrom f = f : StringBuilder member __.Combine(f,g) = B(fun b -> !f b; !g b) member __.Delay f = B(fun b -> !(f ()) b) : StringBuilder member __.Zero () = B(fun _ -> ()) member __.For (xs : 'a seq, f : 'a -> StringBuilder) = B(fun b -> let e = xs.GetEnumerator () while e.MoveNext() do !(f e.Current) b) member __.While (p : unit -> bool, f : StringBuilder) = B(fun b -> while p () do !f b) let string = new StringBuilderM () // example let bytes2hex (bytes : byte []) = string { for byte in bytes -> sprintf "%02x" byte } |> build