我正在尝试阅读 Haskell 包 Data.List.Class 的源代码。(列表-0.4.2)。但我坚持使用一些语法。
开头是这样写的:
data ListItem l a =
Nil |
Cons { headL :: a, tailL :: l a }
我不熟悉第 3 行的语法。我猜这最后一行相当于Cons a (l a)
???。但我不太确定。我注意到文件的标题说:{-# LANGUAGE FlexibleContexts, TypeFamilies #-}
.
然后,随着我的继续,该type
语句有一个奇怪的用法: type ItemM l :: * -> *
,我无法理解。
Data.List.Class
-- | A class for list types. Every list has an underlying monad.
class (MonadPlus l, Monad (ItemM l)) => List l where
type ItemM l :: * -> *
runList :: l a -> ItemM l (ListItem l a)
joinL :: ItemM l (l a) -> l a
cons :: a -> l a -> l a
cons = mplus . return
谁能帮忙解释一下这些是什么意思?我对 Data.List 有一个完美的理解,但是这个类型类的东西对我来说并不是很清楚。我还搜索了有关使用 Data.List.{Class,Tree} 的 wiki、示例和/或教程,但似乎没有任何内容,除了代码附带的注释。这里有任何指示吗?
谢谢。
-- 更新 -- 第一个答案 (@Chris) 帮助我理解了 Kind 签名和 Record 语法,这真的很有帮助。但是,就它如何捕获/定义 List 的行为以及它为熟悉的 Data.List 定义增加什么价值而言,我仍然无法从整体上理解那段代码。这里有一些进一步的细节,其中只有两个实例语句。该Identity
术语也来自import Data.Functor.Identity (Identity(..))
. 你能帮忙解释一下这是什么类型类来捕捉我们通常知道的列表的特征吗?同样,我在网上搜索了它,但除了代码本身之外,实际上没有 Data.List.Class 的文档。有谁知道?
此外,在 typeclass 约束中是否有另一个示例使用该type
语句,类似于本示例中的内容?我搜索了 learnyouahaskell.com/ (@Landei) 但找不到这样的例子。我假设type
这里的用法类似于typedef
在 C++ 模板中使用 's 来定义“类型上的函数”,对吧?
再次感谢。
instance List [] where
type ItemM [] = Identity
runList [] = Identity Nil
runList (x:xs) = Identity $ Cons x xs
joinL = runIdentity
cons = (:)
instance Functor m => Functor (ListItem m) where
fmap _ Nil = Nil
fmap func (Cons x xs) = Cons (func x) (fmap func xs)