对象表达式作为计算生成器

时间:2017-10-10 19:38:34

标签: f#

给出类似

的通用接口声明
type IFoo<'T,'MT> =
    abstract Return : 'T -> 'MT
    abstract Bind : 'MT * ('T -> 'MT) -> 'MT

实际上可以使用对象表达式作为计算构建器表达式,这可以为monadic工作流的封装和执行逻辑之间的划分提供一种有趣的方法。

let inline addOption mx my = 
    {   new IFoo<_,_> with
        member __.Return x = Some x
        member __.Bind(ma, f) = Option.bind f ma }
        {   let! x = mx
            let! y = my
            return x + y }
// val inline addOption :
//   mx: ^a option -> my: ^a option ->  ^a option
//     when  ^a : (static member ( + ) :  ^a *  ^a ->  ^a)

addOption (Some 1) (Some 2)
// val it : int option = Some 3
addOption None (Some 2)
// val it : int option = None

如果存在预期的方法,编译器会检查表达式的类型。但它只有一半;因为对于真正的monad,我需要获得方法签名abstract Bind : 'MT * ('T -> 'MU) -> 'MU,这是对不同非封装类型的投影。为什么不能这样做?

0 个答案:

没有答案