Skip to content


Subversion checkout URL

You can clone with
Download ZIP


StringBuilder monad #201

forki opened this Issue · 4 comments

3 participants



do we want to add this: ?



This seems to be an ad-hoc Reader with a bit of sugar. FSharpx can already do this if we add Yield or better YieldFrom to ReaderBuilder:

open System
open System.Text

type StringBuilder with
    static member append (s: string) (sb: StringBuilder) = sb.Append s |> ignore

let runToString (r: StringBuilder -> unit) =
    let b = StringBuilder()
    r b


type ReaderBuilderYieldFrom() =
    inherit FSharpx.Reader.ReaderBuilder()
    member this.YieldFrom a = base.ReturnFrom a

let readerYF = ReaderBuilderYieldFrom()

let bytes2hex (bytes: byte[]) =
    readerYF {
        for byte in bytes do 
            yield! StringBuilder.append (sprintf "%02x" byte)


type ReaderBuilderYield() =
    inherit FSharpx.Reader.ReaderBuilder()
    member this.Yield a = base.ReturnFrom a // we should probably NOT do this, as it doesn't match the standard signature of yield

let readerY = ReaderBuilderYield()

let bytes2hex' (bytes: byte[]) =
    readerY {
        for byte in bytes ->
            StringBuilder.append (sprintf "%02x" byte)


let result = bytes2hex "abcde"B |> runToString
printfn "%s" result

So to sum up:

  • I don't think we should add that computation expression wrapper for StringBuilder.
  • I think we should add Yield = Return and YieldFrom = ReturnFrom to all our monadic computation expressions.

On second thought, I think it's best if we leave ReaderBuilder as it is, and in this example I'd write:

let bytes2hex3 (bytes: byte[]) =
    FSharpx.Reader.reader {
        for byte in bytes do
            do! StringBuilder.append (sprintf "%02x" byte)

which emphasizes the monadic effect much better.


@mausch I like your last statement. I don't think we want to equate Yield and Return by default. That's probably a better discussion to be had on the list, though.


Anyone else want to weigh in? Otherwise I'll close this.

@ghost ghost closed this
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.