保留数据类型的列表操作

Fil*_*erg 0 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
Run Code Online (Sandbox Code Playgroud)

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

lef*_*out 6

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

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

后两者不太适用,Dictionary因为它不是包含类型的参数.您可以通过切换到"单态版本"来规避这一点.

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