Pattern matching equality on tuples in Haskell

ⅰ亾dé卋堺 提交于 2019-12-02 10:40:17

问题


For this function on symmetric equality over tuples,

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

would like to rewrite it using pattern matching as follows,

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

The latter fails with error on conflicting definitions for x and y. How to rewrite symEq and take benefit of pattern matching ?


回答1:


Unlike in some languages (I hear Erlang works that way), repeating a variable name in patterns in Haskell does not compare the values found at those two places, and is usually an error. So you are going to need to use == for that.

Anyway, here is a slightly more concise way of writing your function:

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

Or even

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



回答2:


With the ViewPatterns you can achieve something that resembles the Erlang and Prolog pattern matching style:

{-# 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

Note how the a in (==a) refers to the first function argument - bound names of earlier function parameters may be used in the view patterns of later parameters.

More details on ViewPatterns may be found here.



来源:https://stackoverflow.com/questions/26601923/pattern-matching-equality-on-tuples-in-haskell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!