我如何拥有多个彼此不交织的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)
最后两个case语句变得混乱起来,我如何告诉SML他们确实是两个独立的case语句,而不是case x为1 => 2的连续/独立分支。
下面的答案中指出的上述模式在通用性方面存在问题。
这段代码有两个明显的问题:
正如John链接到的SML中的嵌套case语句问题所说,case-of s在语法上有些棘手,因为它们的case语句列表永远不会“停止”。也就是说,您的代码实际上被解析为:
fun multi_cases xs =
case xs of
[] => 5
| x::ys => case x of
1 => 2
| _ => 3
| x::[] => case x of
1 => 5
| _ => 7
这是荒谬的,因为该第三种模式应该属于的外部大小写,而不是内部的(内部大小写x
的int处理为int,而外部处理x::[]
为int list)。
由于您的缩进并不能有效地帮助编译器达到预期的含义,因此可以使用括号来阻止大小写的纠缠,就像该帖子所说的那样:
fun multi_cases xs =
case xs of
[] => 5
| x::ys => (case x of
1 => 2
| _ => 3)
| x::[] => (case x of
1 => 5
| _ => 7)
或者,您可以将外部大小写转换为函数参数本身的匹配项,并将内部大小写混合在一起,因为单个模式匹配允许任意深度匹配:
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] => ...
| [] => ...
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句