Types SML数据类型匹配冗余产生冗余

Types SML数据类型匹配冗余产生冗余,types,sml,Types,Sml,我从小米勒那里得到了这个 还有这个 datatype fish = Anchovy | Lox | Tuna 这个工作代码是什么 fun rem_fish (f, fp) = let fun eq_fish (Anchovy,Anchovy) = true | eq_fish (Lox,Lox) = true | eq_fish (Tuna,Tuna) = true

我从小米勒那里得到了这个

还有这个

datatype fish =
         Anchovy
         | Lox
       | Tuna
这个工作代码是什么

fun rem_fish (f, fp) =
    let
        fun eq_fish (Anchovy,Anchovy) = true
          | eq_fish (Lox,Lox) = true
          | eq_fish (Tuna,Tuna) = true
          | eq_fish (_,_) = false
    in
        case fp of
            Bottom => Bottom
          | Topping(x,y) =>
            case eq_fish (f,x) of
                true => rem_fish (f,y)
              | false => Topping (x,rem_fish (f,y))
end
在第一个参数中,它将获取一种鱼和一对鱼比萨饼,并移除特定的鱼

- rem_fish (Tuna, Topping (Tuna, (Topping (Anchovy, Topping (Lox, Topping (Tuna, Bottom))))));
Topping (Anchovy,Topping (Lox,Bottom)) : fish pizza
很好,然后我看到这段代码(我改为基于大小写)标记为“不合语法”

但是这个错误

Error: match redundant
:           Bottom => ...
:           Topping (f,fp') => ...
:     -->   Topping (x,fp') => ...
这个错误意味着什么?代码怎么了?最后一行可能是这样的

Topping (_,fp') => Topping (?,rem_fish (f,fp'))

但是我不知道
可能是什么。

我认为如果我们在代码中消除一些不必要的阴影,它可能会变得更清晰。 考虑函数

fun rem_鱼(f,fp)=
案例fp
底部=>底部
|打顶(y,fp')=>rem_鱼(y,fp'))
|打顶(x,fp')=>打顶(x,rem_fish(f,fp'))
这相当于你写的

注意
Topping(y,fp')
Topping(x,fp')
对于
Topping
变体来说都是无可辩驳的模式;他们会永远匹配的。因此,在您的代码中,如果您有一个
Topping
,它将始终与
案例的第二个分支相匹配,因此第三个分支是多余的(错误是怎么说的)

如果希望能够检查由
Topping
包装的元组中的第一个元素是否等于
f
,则需要使用
op=
(强制它为相等类型)显式执行此操作,或者使用某种相等函数作为参数进行检查(或者像在最初的示例中一样在内部使用它)

fun rem_鱼(u,底部)u=Bottom
|rem_鱼(f,顶部(x,fp))cmp=
如果cmp(f,x),那么
rem_鱼(f,fp)
其他的
浇头(x,rem_鱼(f,fp))

(这对于除具有相等函数的鱼之外的Topping来说可能更一般一些)

但是为什么我的第二个分支
|Topping(f,fp')=>…
中的
f
与传入参数
f
不匹配?当然,带有
Topping(y,fp')
Topping(x,fp'))
x
y
是可互换的,即SML不认为在
y
上匹配,然后在非-y
x
上匹配。但是,同样,
f
是要匹配的传入
fish
的变量。在这种情况下,分支中的
f
只是一个新的(无可辩驳的)模式;作为参数的
f
并不相同。类似于当元组的两个元素相同时(尽管这一个元素出现了错误),不能让
fn(x,x)=>true | u=>false这样的函数匹配第一种情况SML不知道如何比较,看看那些是相等的。考虑你的代码类型> ReMyFISH < /代码>与冗余匹配:你试图比较任何两个值的类型<代码> a <代码>的情况下是平等的;这是没有意义的。你需要一些方法来实现那个比较。原来的“不语法”。本书中的版本给出了
…| rem_fish(x,Topping(x,p))=rem_fish(x,p)…
,该版本存在相同的问题,在模式中产生相同的错误
重复变量:x
Error: match redundant
:           Bottom => ...
:           Topping (f,fp') => ...
:     -->   Topping (x,fp') => ...
Topping (_,fp') => Topping (?,rem_fish (f,fp'))