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

给定一个通用的接口声明

type IFoo<'T,'MT> =
    abstract Return : 'T -> 'MT
    abstract Bind : 'MT * ('T -> 'MT) -> 'MT

实际上可以将对象表达式用作计算构建器表达式,这可以提供一种有趣的方法来分割单向工作流的封装和执行逻辑。

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

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

链接地址: http://www.djcxy.com/p/24425.html

上一篇: Object Expression as Computation Builder

下一篇: F# "exit early" computation expression?