F#要么monad(ROP)要用两个参数组成函数

时间:2017-01-12 07:56:56

标签: f# functional-programming

我正在使用辅助函数的chessie库来做ROP(monad) https://github.com/fsprojects/Chessie/blob/master/src/Chessie/ErrorHandling.fs

但是我不确定如何简洁地将以下三个功能组合在一起。仅当func1和func2返回成功时才应评估twoInputFunc

val func1 : int -> Result<Tp1, 'a>
val func2 : string -> Result<Tp2, 'a>
val twoInputFunc : par1:Tp1 -> Tpar2:Tp2 -> Result<Ta,'a>

1 个答案:

答案 0 :(得分:10)

我认为这应该有效:

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

这个想法是你将每个结果绑定到ab,然后用作最后一个函数调用的输入。如果func1或func2导致错误,它将短路并返回错误。

另一种方法是使用applicatives:

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

这里你在Applicative样式中应用这两个参数,但是你最终会得到一个Result of Result,所以你需要展平它,这相当于monad join操作。

免责声明:我没有安装Chessie,所以我没有尝试过上面的代码,但是我尝试使用FSharpPlus,它对所有monad都是通用的(不仅仅是Either)而且它工作正常(使用monad代替trialjoin代替flatten)。