F#中的自定义计算表达式

时间:2009-12-16 20:40:41

标签: f# computation-expression

我一直在玩F#(也就是计算表达式)中的monads,我写了这个简单的Identity monad:

type Identity<'a> = 
    | Identity of 'a

type IdentityBuilder() =
    member x.Bind (Identity v) f  = f(v)
    member x.Return v = Identity v
let identity = new IdentityBuilder()

let getInt() = identity { return Int32.Parse(Console.ReadLine()) }

let calcs() = identity {
    let! a = getInt()    // <- I get an error here
    let! b = getInt()
    return a + b }

我不明白我在标记线上的错误:

  

预计此表达式的类型为Identity&lt;'a&gt;但这里有'b *'c

类型

我认为这没有意义,因为getInt()显然是Identity<'a>类型的值。

谁能告诉我我做错了什么?

2 个答案:

答案 0 :(得分:9)

计算表达式语法希望Bind具有一个tupled,而不是curried参数。 所以

member x.Bind((Identity v), f) = f(v)

有关所有签名,请参阅this article

答案 1 :(得分:3)

问题是你的Bind函数的类型 - 它不应该采用curried参数。如果您将其更改为:

member x.Bind (Identity v, f)  = f(v)

然后它应该工作。