Haskell data.list.class用法

时间:2012-08-07 11:11:53

标签: list haskell typeclass

这是关于Data.List.Class的使用问题的问题(与Haskell Data.List.Class and syntax上的上一个问题相关)。

下面列出了相关的代码段。根据我的理解,这个类为Haskell列表类型提供了一个类型类接口或泛化,这可能非常有用。但是,我真的找不到关于这个类的用法的文档。有没有人知道一个好的教程?

另外,我对其用法和类型有技术/具体问题。从代码中,我认为在类型类定义中,runList和joinL是彼此的反转(在某种意义上)。

-- other stuff omitted
import Data.Functor.Identity (Identity(..))

data ListItem l a =
    Nil |
    Cons { headL :: a, tailL :: l a }

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

instance List [] where
    type ItemM [] = Identity
    runList [] = Identity Nil
    runList (x:xs) = Identity $ Cons x xs
    joinL = runIdentity
    cons = (:)

fromList :: List l => [a] -> l a
fromList = foldr cons mzero

首先,我在emacs模式下输入joinL $ runList [1, 2, 3],但我收到以下错误:

Couldn't match type `ItemM (ListItem [])' with `Identity'
Expected type: ItemM (ListItem []) (ListItem [] Integer)
  Actual type: ItemM [] (ListItem [] Integer)

正如它所说,预期和实际类型并不完全匹配。但我不明白为什么他们首先应该要求不同的类型。 runList :: l a -> ItemM l (ListItem l a)joinL :: ItemM l (l a) -> l a在含义或语义方面有何不同?

另外,我在emacs模式下尝试了一个非常简单的fromList函数,如下所示:fromList [1,2,3],但我得到了:

Ambiguous type variable `l0' in the constraint:
  (List l0) arising from a use of `fromList'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: fromList [1, 2, 3]
In an equation for `it': it = fromList [1, 2, 3]

我很困惑,为什么这里存在歧义,以及如何在错误消息提示时添加类型签名。任何人都可以帮忙解释一下吗?

提前致谢,

1 个答案:

答案 0 :(得分:1)

对于上一个问题:它可能是几种实现List类型类的类型,如果以后不推文,你应该指定它。例如,fromList [1, 2, 3] :: [Int]工作正常。