简体   繁体   English

Haskell和Erlang中的模式匹配

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM