我来自 Little MLer
datatype 'a pizza =
Bottom
| Topping of ('a * ('a pizza))
还有这个
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
很好,因此我看到此代码(我已更改为基于case
),并标记为“不合语法”
fun rem_fish (f, fp) =
case fp of
Bottom => Bottom
| Topping (f,fp') => rem_fish (f,fp')
| Topping (x,fp') => Topping (x,rem_fish (f,fp'))
但是这个错误
Error: match redundant
: Bottom => ...
: Topping (f,fp') => ...
: --> Topping (x,fp') => ...
此错误是什么意思?代码有什么问题?最后一行可能是这样的
Topping (_,fp') => Topping (?,rem_fish (f,fp'))
但是后来我不知道?
会是什么。
答案 0 :(得分:1)
我认为,如果我们在这段代码中消除一些不必要的阴影,可能会变得更加清晰。 考虑一下功能
fun rem_fish (f, fp) =
case fp of
Bottom => Bottom
| Topping (y,fp') => rem_fish (y,fp')
| Topping (x,fp') => Topping (x,rem_fish (f,fp'))
等同于您所写的内容。
请注意,Topping (y,fp')
和Topping (x,fp')
都是Topping
变体的不可辩驳的模式;他们将永远匹配它。因此,在您的代码中,如果您有一个Topping
,它将始终与case
的第二个分支匹配,因此,第三个分支是多余的(错误在说什么)。
如果您希望能够检查Topping
包装的元组中的第一个元素是否等于f
,则需要使用op=
(强制将其作为相等类型),或将某种相等函数用作参数进行检查(或像在初始示例中那样在内部将其用作内部)。后者可能看起来像
fun rem_fish (_, Bottom) _ = Bottom
| rem_fish (f, Topping (x, fp)) cmp =
if cmp (f, x) then
rem_fish (f, fp)
else
Topping (x, rem_fish (f, fp))
(除了具有相等功能的鱼以外,其他浇头的使用可能会更普遍)