[英]Pattern-matching in Haskell and Erlang
I have a small Erlang function that compares if two lists are equal: 我有一个小的Erlang函数,比较两个列表是否相等:
myEq([], []) -> true;
myEq([X|Xs], [X|Ys]) -> myEq(Xs, Ys);
myEq(_, _) -> false.
The comparison takes place on line 2, the X
of [X|Xs]
always binds to the first element of the first list, the [X|Ys]
matches only if the first elements of both lists are equal. 比较发生在第2行中, X
的[X|Xs]
总是结合到第一列表的第一元件,所述[X|Ys]
匹配仅在这两个列表的第一元素是相等的。
If I try this in Haskell I get an error message: " Conflicting definitions for x
". 如果我在Haskell中尝试这个,我会收到一条错误消息:“ x
定义冲突 ”。 A possible solution in Haskell would be: Haskell中可能的解决方案是:
myEq (x:xs) (y:ys) = if x == y then myEq xs ys else False
But I would like to know if it is possible to do this in Haskell using pattern matching? 但我想知道是否可以使用模式匹配在Haskell中执行此操作?
No, in Haskell you cannot use the same variable x
in the head of a clause. 不,在Haskell中,您不能在子句的头部使用相同的变量x
。 Haskell does not do unification or equality checks like for instance respectively Prolog and Erlang do. Haskell 没有做统一或相等检查例如像分别序言和Erlang做。 This is specified in the Haskell '98 report: 这在Haskell '98报告中指定:
The set of patterns corresponding to each match must be linear--- no variable is allowed to appear more than once in the entire set. 对应于每个匹配的模式集必须是线性的 - 不允许变量在整个集合中出现多次 。
(copied, boldface added) (复制,粗体添加)
The only way to do it is using a guard (or any other type of checking in the body of course). 唯一的方法是使用警卫(或当然体内任何其他类型的检查)。 You can however write it more elegant like: 但是你可以写得更优雅,如:
myEq [] [] = True
myEq (x:xs) (y:ys) | x == y = myEq xs ys
-- | otherwise = False
myEq _ _ = False
the otherwise
case can be omitted since Haskell will fallback on the last clause and thus return False
. 由于Haskell将在最后一个子句上回退并因此返回False
,因此可以省略otherwise
情况。
Or perhaps even more elegant: 或者更优雅:
myEq [] [] = True
myEq (x:xs) (y:ys) = x == y && myEq xs ys
myEq _ _ = False
Personally I think that is better since here you state explicitly that x
is equal to y
so making mistakes like by accident writing the same variable cannot happen. 我个人认为这更好,因为在这里你明确声明x
等于y
所以犯错误就像意外写同一个变量一样。 Although of course it is a matter of taste. 虽然当然这是一个品味问题。
No. Every variable can be bound at most once on the pattern matching side. 不可以。在模式匹配方面,每个变量最多只能绑定一次。 If you wanted to bind a variable twice you would have to evaluate to perform unification. 如果要将变量绑定两次,则必须进行求值以执行统一。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.