FSharpx and Railway Oriented Programming

Olav Nybø

TL;DR: Railway Oriented Programming (ROP) is a technique that enable us to write clutter free code. FSharpx.Core is a nuget package that has the building blocks needed for ROP in addition to much more.

I first heard about Railway Oriented Programming from Scott Wlaschin in his NDC2014 talk on the subject. Its so pleasant to read code written in this style. It enable us to write the steps of a process as if we only had to consider the happy path, while still being able to handle all that may go wrong.
The code below is a simple example function showing what a simple 3 step process may look like.

let myProcess =
  succeed start
  >>= step1
  >>= step2
  >>= step3 

The output of each step is fed into the next if everything goes well, otherwise a error is passed and the following steps will be skipped. The final result will be the successfull result of the last step or an error.

Scott Wlaschin has published a project on github Railway-Oriented-Programming-Example which demonstrates how to do this.
His demo includes several operators and functions needed to implement this style, these are bind (>>=), apply (<*>), map/lift ().
This is all well in a demo application where the purpose is to explain these functions, but in other applications it is nice to not have to repeat this code.
This is where FSharpx come in. FSharpx is a library of handy and useful functions that extends the base libraries for F#, and it includes all the above mentioned functions.
It is of course available on nuget.org and is quickly installed into any project by installing package named: fsharpx.core.

Unfortunately the documentation for the library is almost non-existant but the functions used for ROP are all located in the module: FSharpx.Choice and they work very similar to the ones written by Wlaschin.
One difference is that they work with the Choice union type from the Microsoft core library (Microsoft.FSharp.Core) instead of the RopResult that Wlaschins code works with.
Except from this they are pretty much the same.

protect is another usefull function from the same module. It is used when calling code that may throw exceptions and turn any exception into a error wrapped in a Choice.
The complete list of functions in the choice module can be found here

comments powered by Disqus