我有以下代码
type Position = (Int,Int)
data CheckError where
LError :: Position -> LexerError -> CheckError
PError :: Position -> ParseError -> CheckError
SError :: Position -> StaticError -> CheckError
我需要它来实例Ord
,只需比较每个构造函数中的Position
字段。
我得到了它的工作:
data CheckError where
LError :: Position -> LexerError -> CheckError
PError :: Position -> ParseError -> CheckError
SError :: Position -> StaticError -> CheckError
deriving (Show)
instance Eq CheckError where
(LError l _) == (LError r _) = l == r
(LError l _) == (PError r _) = l == r
(LError l _) == (SError r _) = l == r
(PError l _) == (LError r _) = l == r
(PError l _) == (PError r _) = l == r
(PError l _) == (SError r _) = l == r
(SError l _) == (LError r _) = l == r
(SError l _) == (PError r _) = l == r
(SError l _) == (SError r _) = l == r
instance Ord CheckError where
compare (LError l _) (LError r _) = l `compare` r
compare (LError l _) (PError r _) = l `compare` r
compare (LError l _) (SError r _) = l `compare` r
compare (PError l _) (LError r _) = l `compare` r
compare (PError l _) (PError r _) = l `compare` r
compare (PError l _) (SError r _) = l `compare` r
compare (SError l _) (LError r _) = l `compare` r
compare (SError l _) (PError r _) = l `compare` r
compare (SError l _) (SError r _) = l `compare` r
但我觉得这段代码太重复了。有没有办法告诉Haskell直接与Position
字段进行比较?
答案 0 :(得分:7)
也许这样?
instance Eq CheckError where
a == b = pos a == pos b
where
pos (LError p _) = p
pos (PError p _) = p
pos (SError p _) = p
答案 1 :(得分:3)
我建议使用来自on
的{{1}}组合器稍微清洁一点:
Data.Function
其中import Data.Function
instance Eq CheckError where
(==) = (==) `on` pos
instance Ord CheckError where
compare = compare `on` pos
被定义为简单函数或记录字段(由@Xavier建议)。这可以简单地解读为“pos
的比较是对他们立场的比较”。