我正在研究一些F#并尝试实现像this tutorial中那样的解析器组合器;在对提议的解决方案进行一些复制和粘贴之后,我尝试自己定制它。
肯定有一些我错过了但编译器给了我一个奇怪的错误信息。
type T<'a> =
| A of string
| B of 'a
let foo a b =
match a with
| A s as x -> x
| B i ->
match b with
| A s as x -> x
| B j ->
B (i, j)
上面的代码是我发现的问题的概括:在最后一个结果(最里面的匹配表达式的B分支)中通知错误:
error FS0001: Type mismatch. Expecting a
'a
but given a
'a * 'b
The resulting type would be infinite when unifying ''a' and ''a * 'b'
但如果我不使用as
模式:
let foo a b =
match a with
| A s -> A s // it can also be '| A s as x -> A s'
| B i ->
match b with
| A s -> A s
| B j ->
B (i, j)
然后编译器再次开心。
我不明白为什么我必须重新创建相同的逻辑结果(如果它已经存在)。
答案 0 :(得分:7)
在
A s as x -> x
x
的类型为T<'a>
,foo
所需的返回类型为T<('a * 'a)>
。即使A
案例不包含'a
的任何值,它也不具有像forall 'a . T<'a>
这样的多态类型。在第二个示例中,您将创建一个A
的新实例,该实例可以具有所需的类型。