I am working on understanding Railway Oriented Programming (Scott Wlaschin style) in F#. In my example I want to create a pipeline which does some calculation, applies two different functions to the output of that initial calculation, then hands off a tuple of its results to a final function.
In real code the 'initial calculation' might be getting some data, the 'two different functions' might produce a textual summary and a chart of the data, and the final function might be rendering some output containing both the text and the chart.
I've invented a
bind2 function to achieve this, but I can't help thinking that if this was a good idea it would already be common practice and must appear (in disguise) in existing libraries such as Scott's.
Please let me know how I would achieve what I want in an idiomatic style.
Here's my code. All above
bind2 is taken broadly from Scott's code, the remainder is my
bind2 function and a simple demo.
type Result<'S, 'F> = | Success of 'S | Failure of message : 'F list let bind f x = match x with | Success s -> f s | Failure f -> Failure f let bind2 (f1 : 'A -> Result<'B, 'F>) (f2 : 'A -> Result<'C, 'F>) (x : Result<'A, 'F>) : Result<'B * 'C, 'F> = match x with | Success _ -> let r1, r2 = (bind f1) x, (bind f2) x match r1, r2 with | Success s1, Success s2 -> Success(s1, s2) | Failure f1, _ -> Failure f1 | _, Failure f2 -> Failure f2 | Failure f -> Failure f let demo1 (a: int) : Result<int, string> = Success a let demo2 (a: int) : Result<string, string> = a |> string |> Success let demo3 (a: int) : Result<string, string> = a |> (*) -1 |> string |> Success let demo4 (s1 : string, s2 : string) = sprintf "%s - %s" s1 s2 |> Success let Demo = bind demo1 >> bind2 demo2 demo3 >> bind demo4