假设我有以下代码:
import Data.List.Ordered
data Person = Person String String
deriving (Show, Eq)
main :: IO ()
main = print . show . sort $ [(Person "Isaac" "Newton"), (Person "Johannes" "Kepler")]
在同一模块中,我希望能够按名字和姓氏对列表进行排序。显然我不能这样做:
instance Ord Person where
compare (Person _ xLast) (Person _ yLast) = compare xLast yLast
instance Ord Person where
compare (Person xFirst _) (Person yFirst _) = compare xFirst yFirst
那么,我有什么选择呢?
这一页提到“您可以通过将类型包装在新类型中并将所有必需的实例提升为该新类型来实现此目的。”有人可以举个例子吗?
有没有更好的办法?
新类型方法将是:
newtype ByFirstname = ByFirstname { unByFirstname :: Person }
instance Ord ByFirstname where
-- pattern matching on (ByFirstname (Person xFirst _)) etc
compare [...] = [...]
newtype ByLastname = ByLastname { unByLastname :: Person }
instance Ord ByLastname where
-- as above
那么排序函数将类似于:
sortFirstname = map unByFirstname . sort . map ByFirstname
类似地对于ByLastname
.
更好的方法是使用sortBy
, compare
and on
,具有检索名字和姓氏的函数。 IE。
sortFirstname = sortBy (compare `on` firstName)
(在这一点上,可能值得使用记录类型Person
, i.e. data Person = Person { firstName :: String, lastName :: String }
,甚至可以免费获得访问器功能。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)