Skip to content

Instantly share code, notes, and snippets.

@dvdsgl
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dvdsgl/eac75ee61a811ce72764 to your computer and use it in GitHub Desktop.
Save dvdsgl/eac75ee61a811ce72764 to your computer and use it in GitHub Desktop.
Implement Writer monad with custom keyword.
type Writer<'Result, 'Output> =
| W of 'Result * seq<'Output>
type WriterBuilder() =
member this.Zero() = W ((), Seq.empty)
member this.Yield(x) = W (x, Seq.empty)
member this.Return(x) = this.Yield(x)
member this.Bind(W (a, xs), k) =
let (W (b, ys)) = k a
W (b, Seq.append xs ys)
[<CustomOperation("write", MaintainsVariableSpace=true)>]
member this.Write(W (a, xs), x) =
W (a, Seq.append xs (Seq.singleton x))
let writer = WriterBuilder()
let logger = writer {
write "Hello"
write "World"
write "David"
}
let runWriter (W (a, xs)) = xs
[<EntryPoint>]
let main argv =
printfn "Wrote out: %A" (runWriter logger)
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment