6

我一直在玩 F#(又名计算表达式)中的 monad,我写了这个简单的 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<'a> 但此处具有类型 'b * 'c

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

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

4

2 回答 2

9

计算表达式语法希望Bind有一个元组,而不是柯里化参数。所以

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

请参阅本文以获取所有签名。

于 2009-12-16T20:46:49.030 回答
3

问题是你的Bind函数的类型——它不应该接受咖喱参数。如果您将其更改为:

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

那么它应该可以工作。

于 2009-12-16T20:46:21.253 回答