Computation expressions in a nutshell are syntactic transforms for F# code, just like `let_with_check`

in the previous example. Let’s
look at how you can leverage F#’s support for computation expressions to
simplify your code.

Example 10-4 shows how
to create a custom workflow. We’ll go over what’s going on behind the
scenes in a moment. For now, just look at the implementation of the
`Bind`

method, the
`defined { }`

block, and
the use of the `let!`

keyword.

Example 10-4. The success/failure computation expression

type Result = Success of float | DivByZero let divide x y = match y with | 0.0 -> DivByZero | _ -> Success(x / y) type DefinedBuilder() =// If the result is Success(_) then execute the // rest of the function. Otherwise terminate it // prematurely. match x with | Success(x) -> rest x | DivByZero -> DivByZero member this.Return (x : 'a) = x // Create an instance of our computation expression builder let defined = DefinedBuilder() let totalResistance r1 r2 r3 =`member this.Bind ((x : Result), (rest : float -> Result)) =`

`defined {`

x = divide 1.0 r1`let!`

y = divide 1.0 r2`let!`

z = divide 1.0 r3 return divide 1.0 (x + y + z)`let!`

`}`

You can test this in FSI and verify that the computation expression version gets the same results, and in one-third the lines of code!

> totalResistance 0.01 0.75 0.33;; val it : Result = Success 0.009581881533 > totalResistance 0.00 0.55 0.75;; val it : Result = DivByZero

All computation expressions do is break the expression ...

Start Free Trial

No credit card required