Last active
August 29, 2015 14:08
-
-
Save brodyberg/c0acd46d83c08facc493 to your computer and use it in GitHub Desktop.
F# Computation Expression.Bind Explained in the Simplest Possible Language
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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