对于关于元组对称相等的这个函数,
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
后者因x
和y
的定义冲突错误而失败。如何重写symEq
并利用模式匹配?
答案 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。