Last active
August 29, 2015 13:56
-
-
Save lasandell/9161684 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// Computation expression builder that uses a custom bind operation | |
// to allow binding a value to a name and yielding it as part of a | |
// list in one go. | |
type ListBuilder() = | |
member this.Bind(x, f) = x::f(x) | |
member this.Delay(f) = f() | |
member this.Combine(x, xs) = x @ xs | |
member this.Yield(x) = [x] | |
let list = ListBuilder() | |
// Produces [2, 4, 8, 16] | |
list { | |
let! x = 2 | |
let! x2 = x * x | |
let! x3 = x2 * x | |
yield x3 * x | |
} | |
// Equivalent list comprehension | |
[ | |
let x = 2 | |
yield x | |
let x2 = x * x | |
yield x2 | |
let x3 = x2 * x | |
yield x3 | |
yield x3 * x | |
] | |
// It would be kind of cool if this "let!" behavior was in the built-in list comprehensions and | |
// sequence expressions. Another thing that would be nice is if I could do "let! x4 = x3 * x" at | |
// the end of the first snippet for a uniform syntax. It doesn't really make sense to end an | |
// expression with a normal let binding, but a custom one might make sense since it can have a | |
// different behavior. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment