Haskell中元组上的模式匹配相等

时间:2014-10-28 06:12:59

标签: haskell pattern-matching tuples equality

对于关于元组对称相等的这个函数,

symEq :: Eq a => (a,a) -> (a,a) -> Bool
symEq (x,y) (u,v) = (x,y) == (u,v) || (x,y) == (v,u)

希望使用模式匹配重写它,如下所示,

symEq' :: Eq a => (a,a) -> (a,a) -> Bool
symEq' (x,y) (x,y) = True
symEq' (x,y) (y,x) = True
symEq' _ _ = False

后者因xy的定义冲突错误而失败。如何重写symEq并利用模式匹配?

2 个答案:

答案 0 :(得分:6)

与某些语言(我听说Erlang以这种方式工作)不同,在Haskell中的模式中重复变量名称​​不比较在这两个地方找到的值,并且通常是错误。因此,您需要使用==

无论如何,这是一个略微更简洁的函数编写方式:

symEq t (x,y) = t == (x,y) || t == (y,x)

甚至

symEq t (x,y) = t `elem` [(x,y), (y,x)]

答案 1 :(得分:3)

使用ViewPatterns,您可以实现类似于Erlang和Prolog模式匹配样式的东西:

{-# LANGUAGE ViewPatterns #-}

swap (a,b) = (b,a)

symEq :: Eq a => (a,a) -> (a,a) -> Bool
symEq a ((==a) -> True) = True
symEq a ((==a).swap -> True) = True
symEq _ _ = False

注意a中的(==a)如何引用第一个函数参数 - 早期函数​​参数的绑定名称可以用在后面参数的视图模式中。

可以找到有关ViewPatterns的更多详细信息here