F#匹配表达式和'as'模式

时间:2017-06-28 15:34:32

标签: f# pattern-matching

我正在研究一些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)

然后编译器再次开心。

我不明白为什么我必须重新创建相同的逻辑结果(如果它已经存在)。

1 个答案:

答案 0 :(得分:7)

A s as x -> x

x的类型为T<'a>foo所需的返回类型为T<('a * 'a)>。即使A案例不包含'a的任何值,它也不具有像forall 'a . T<'a>这样的多态类型。在第二个示例中,您将创建一个A的新实例,该实例可以具有所需的类型。