Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# either monad (ROP) to to compose function with two parameters

I am using the chessie library of helper functions to do ROP (either monad) https://github.com/fsprojects/Chessie/blob/master/src/Chessie/ErrorHandling.fs

However I'm not sure how to concisely compose the following three functions together. Where twoInputFunc should be evaluated only if func1 and func2 return success.

val func1 : int -> Result<Tp1, 'a>
val func2 : string -> Result<Tp2, 'a>
val twoInputFunc : par1:Tp1 -> Tpar2:Tp2 -> Result<Ta,'a>
like image 784
Chinwobble Avatar asked Dec 23 '22 21:12

Chinwobble


1 Answers

I think this should work:

let f x y = trial {
    let! a = func1 x
    let! b = func2 y
    return! twoInputFunc a b}

The idea is that you bind each result to a and b and then are used as input for the last function call. If either func1 or func2 results in an Error it will short circuit and return the Error.

Another way is using applicatives:

let g x y = flatten (twoInputFunc <!> func1 x <*> func2 y)

Here you apply both arguments in an Applicative style but then you will end-up with a Result of Result so you need to flatten it, this is equivalent to the monad join operation.

Disclaimer: I don't have Chessie installed so I didn't tried the above code, but I tried with FSharpPlus which is generic to all monads (not just Either) and it works fine (using monad instead of trial and join instead of flatten).

like image 117
Gus Avatar answered Jan 18 '23 23:01

Gus