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

6

我一直在玩弄F#中的单子(也称为计算表达式),并写了这个简单的Identity单子:

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()显然是类型为Identity<'a>的值。

有人能告诉我我做错了什么吗?

2个回答

9
计算表达式语法要求Bind具有元组化的参数,而不是柯里化的参数。因此,
member x.Bind((Identity v), f) = f(v)

请见此文章了解所有签名。


1
或者查看语言规范的6.4.10节:http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html - Brian
1
自己注意:修改那个维基页面,因为它毫无意义 ;) - Juliet

3
问题在于您的Bind函数类型 - 它不应该采用柯里化参数。如果您将其更改为:
member x.Bind (Identity v, f)  = f(v)

然后它应该可以工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接