On Mon, 12 Dec 2005, Bulat Ziganshin wrote:
Hello
sometimes, Eq/Ord classes can't be derived automatically because we
need to comare only part of fields. in such situations i use the
following trick to easify generation of class instances:
data ArchiveBlock = ArchiveBlock {
blArchive :: Archive
, blType :: BlockType
, blCompressor :: Compressor
, blPos :: Integer
, blOrigSize :: Integer
, blCompSize :: Integer
, blCRC :: CRC
, blFiles :: Int
}
instance Eq ArchiveBlock where
(==) = map2eq $ map3 (blArchive,blPos,blCRC)
instance Ord ArchiveBlock where
compare = map2cmp $ map2 (blArchive,blPos)
{-
instance Ord ArchiveBlock where
compare = map2cmp blPos -- for comparision on just one field
-}
I solved that problem with two generic functions:
Compare the same item of two records.
compareField :: Ord b => (a -> b) -> a -> a -> Ordering
compareField f x y = compare (f x) (f y)
Lexicographically compare a list of attributes of two records.
compareRecord :: [a -> a -> Ordering] -> a -> a -> Ordering
compareRecord cs x y =
head (dropWhile (EQ==) (map (\c -> c x y) cs) ++ [EQ])
Use it this way:
instance Ord ArchiveBlock where
compare =
compareRecord
[compareField blArchive,
compareField blPos,
compareField blCRC]
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe