保留数据类型的列表操作

时间:2017-01-27 08:34:24

标签: haskell algebraic-data-types

我希望能够定义自定义数据类型,而不是使用类型别名来确保传递正确的值,下面是可能看起来如何的草图,

module Example (fromList) where

import Data.Ord (comparing, Down(..))
import Data.List (sort)

data DictEntry = DictEntry (String, Integer) deriving (Show, Eq)

instance Ord DictEntry where
  (DictEntry (word1, freq1)) `compare` (DictEntry (word2, freq2))
    | freq1 == freq2 = word1 `compare` word2
    | otherwise = comparing Down freq1 freq2

data Dictionary = Dictionary [DictEntry] deriving (Show)

fromList :: [(String, Integer)] -> Dictionary
fromList l = Dictionary $ sort $ map DictEntry l

但是,我还希望保留基础类型的“list-ness”,而不必打开和重新包装[DictEntry],而无需定义实用程序函数,例如head :: Dictionary -> DictEntrytail :: Dictionary -> Dictionary。那可能吗?是否有一些类型类我可以定义一个实例或一个语言扩展来启用它?

1 个答案:

答案 0 :(得分:6)

永远不要使用head并避免使用tail,列表或其他。这些是不安全的,并且总是可以很容易地用模式匹配替换。

但是,是的,有一个类型类支持类似列表的操作,或者更确切地说是多个类。其中最简单的是Monoid,它只实现连接和空初始化。 Foldable,允许您解释容器,就像它们是列表一样。 Traversable还允许您在浏览数据时再次组装它们。

后两者不能与Dictionary完全兼容,因为它不是包含类型的参数。您可以通过切换到“monomorphic version”来规避这一点。

但是,我坦率地认为你不应该这样做 - 只需使用标准Map类型来存储键值关联数据,而不是滚动自己的字典类型。

相关问题