Ral*_*lli 6 erlang haskell pattern-matching
我有一个小的Erlang函数,比较两个列表是否相等:
myEq([], []) -> true;
myEq([X|Xs], [X|Ys]) -> myEq(Xs, Ys);
myEq(_, _) -> false.
Run Code Online (Sandbox Code Playgroud)
比较发生在第2行中,X的[X|Xs]总结合到第一列表的第一元件,所述[X|Ys]匹配项只有当这两个列表的第一元素是相等的.
如果我在Haskell中尝试这个,我会收到一条错误消息:" 冲突的定义x ".Haskell中可能的解决方案是:
myEq (x:xs) (y:ys) = if x == y then myEq xs ys else False
Run Code Online (Sandbox Code Playgroud)
但我想知道是否可以使用模式匹配在Haskell中执行此操作?
Wil*_*sem 10
不,在Haskell中,您不能x在子句的头部使用相同的变量.哈斯克尔并没有做统一或相等检查例如像分别序言和二郎做.这在Haskell '98报告中指定:
对应于每个匹配的模式集必须是线性的 - 不允许变量在整个集合中出现多次.
(复制,粗体添加)
唯一的方法是使用警卫(或当然体内任何其他类型的检查).但是你可以写得更优雅,如:
myEq [] [] = True
myEq (x:xs) (y:ys) | x == y = myEq xs ys
-- | otherwise = False
myEq _ _ = False
Run Code Online (Sandbox Code Playgroud)
otherwise由于Haskell将在最后一个子句上回退并因此返回,因此可以省略该情况False.
或者更优雅:
myEq [] [] = True
myEq (x:xs) (y:ys) = x == y && myEq xs ys
myEq _ _ = False
Run Code Online (Sandbox Code Playgroud)
我个人认为这更好,因为在这里你明确说明x等于y这样做错误就像意外写同一个变量不会发生.虽然当然这是一个品味问题.