我怎样才能有多个不相互交错的case语句。 例如玩具示例:
fun multi_cases(xs) =
case xs of
[] => 5
| x::ys => case x of
1 => 2
|_ => 3
| x::[] => case x of
1 => 5
| _ => 7
;
stdIn:59.17-64.28 Error: types of rules don't agree [overload conflict]
earlier rule(s): [int ty] -> [int ty]
this rule: [int ty] list -> [int ty]
in rule:
:: (x,nil) =>
(case x
of 1 => 5
| _ => 7)
最后两个案例陈述混淆了我怎么能告诉SML他们确实是两个独立的案例陈述而不是案件x的延续/单独分支1 => 2 ...
以下答案中指出的上述模式存在一般性问题。
答案 0 :(得分:2)
此代码有两个不同的问题:
正如约翰所链接的问题Nested case statements in SML所说, case-of 在语法上有点棘手,因为他们的案例陈述列表永远不会#34;停止&#34 ;。也就是说,您的代码实际上被解析为:
fun multi_cases xs =
case xs of
[] => 5
| x::ys => case x of
1 => 2
| _ => 3
| x::[] => case x of
1 => 5
| _ => 7
这是荒谬的,因为第三个模式应该属于外部 case-of 而不是内部(内部 case-of 属于x
作为 int ,外部带x::[]
作为 int列表)。
由于您的缩进不会主动帮助编译器达到预期的含义,因此使用括号来停止"停止"交错的案例,就像帖子所说,是修复:
fun multi_cases xs =
case xs of
[] => 5
| x::ys => (case x of
1 => 2
| _ => 3)
| x::[] => (case x of
1 => 5
| _ => 7)
或者,您可以将外部 case-of 转换为函数参数本身的匹配项,并将内部 case-of 与它混合在一起,因为单个模式匹配允许任意深度匹配:
fun fun_cases [] = 5
| fun_cases [1] = 5
| fun_cases [_] = 7
| fun_cases (1::_) = 2
| fun_cases (_::_) = 3
您的两个案例重叠,因为x::xs
是一种比x::[]
更通用的模式。也就是说,它还通过将x::[]
设置为xs
来涵盖列表[]
。您可以通过以下两种方式之一解决这个问题:
首先列出最不常见的模式,例如
case xs of
[] => 5
| [x] => ...
| x::_ => ...
通过指定列表应至少包含两个元素,将x::xs
一般模式变为不太通用的模式:
case xs of
x :: _ :: _ => ...
| [x] => ...
| [] => ...