Haskell:如何将多个实例放在同一个模块中?

2023-12-05

假设我有以下代码:

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(使用前将#替换为@)

Haskell:如何将多个实例放在同一个模块中? 的相关文章

随机推荐