Skip to content

Instantly share code, notes, and snippets.

@brodyberg
Last active August 29, 2015 14:08
Show Gist options
  • Save brodyberg/c0acd46d83c08facc493 to your computer and use it in GitHub Desktop.
Save brodyberg/c0acd46d83c08facc493 to your computer and use it in GitHub Desktop.
F# Computation Expression.Bind Explained in the Simplest Possible Language
// F# Computation Expressions Explained in the Simplest Way I Know How:
// see end for links
// me: @brodyberg
// EXAMPLE 1: Make a binding that only ever works
// Nothing happens in Bind which interferes with the success
// of the assignment of "bar" to foo or "baz" to bar etc.
type OnlyContinueBuilder () =
// all Bind does is make the binding happen, i.e. apply x to f
member this.Bind(x,f) = f x
member this.Return(x) = x
let onlyContinue = new OnlyContinueBuilder()
onlyContinue
{
// Bindings NEVER fail, yeehaw!
let! foo = "bar"
let! bar = "baz"
let! fooBar = foo + bar
return fooBar
}
// EXAMPLE 2: Make a binding that goofs off and works
// Before we make the bind happen, we do a thing
// In this case we print, but we could also log,
// check the phase of the moon, you name it
type DoAThingAndContinueBuilder () =
let doAThing () = printfn "look, we're doing a thing!"
// Bind does some random thing, AND THEN makes the
// binding happen
member this.Bind(x,f) =
doAThing()
f x
member this.Return(x) = x
let doAThingAndContinue = new DoAThingAndContinueBuilder()
doAThingAndContinue
{
// Binding, and other stuff happens, yay!
let! foo = "bar"
let! bar = "baz"
let! fooBar = foo + bar
return fooBar
}
// EXAMPLE 3: Do some thinking about whether or not to go through with the binding
type InterruptExecutionBuilder () =
let makeADecision (input:string) = if input.Length > 3 then true else false
member this.Bind(x,f) =
if makeADecision x = true then (f x) else System.String.Empty
member this.Return(x) = x
let interruptExecution = new InterruptExecutionBuilder()
interruptExecution
{
let! foo = "bar"
let! bar = "baz"
// KAPOW!!!! the Bind makes a decision - which is to NOT allo
// foo + bar to be assigned to fooBar.
let! fooBar = foo + bar
return fooBar
}
// CONCLUSIONS:
// Computation Expressions give us Bind, which we can use to:
// 1. Do absolutely nothing, and allow a bind
// 2. Do a random thing, and allow a bind
// 3. DECIDE whether or not to bind
// LINKS:
// http://fsharp.org/
// Computation Expressions: http://msdn.microsoft.com/en-us/library/dd233182.aspx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment