直接在Haskell类中定义一个空容器?

时间:2017-09-02 11:13:11

标签: haskell typeclass

我的任务是实现这些功能,但我一开始就陷入困境。

为什么我不能这样写empty? (ghci抱怨:couldn't match type

我不是说[]应该是type m k v吗?

class MapLike m where
    empty :: m k v
    empty = [] :: m k v
    lookup :: Ord k => k -> m k v -> Maybe v

newtype ListMap k v = ListMap { getListMap :: [(k,v)] } deriving (Eq,Show)

1 个答案:

答案 0 :(得分:7)

我认为您混淆的根源可能是Catalina base directory关键字。

忘记所有先入为主的课程概念。 Haskell class实际上与Java中的面向对象语言中的class完全不同。类型类更像是Java class而不是interface

更具体地说,Haskell中的class定义了一个类型可能符合的签名接口。所以当你写

class

您要声明一类类似地图的类型class MapLike m where empty :: m k v lookup :: Ord k => k -> m k v -> Maybe v ,并且为了m :: * -> * -> *,类型必须至少支持MapLikeempty操作。

现在我可以编写适用于任何lookup类型的函数。

MapLike

类型类的实现进入contains :: (MapLike m, Ord k) => m k v -> k -> Bool m `contains` k = case lookup k m of Just _ -> True Nothing -> False 。你说你正在实现哪个instance,你说哪个类型实现了它,然后你给出了在类中声明的函数的实现。所以,在下面,我说classListMap类型,我正在解释MapLikeempty操作如何适用于lookup类型。

ListMap

由于instance MapLike ListMap where empty = ListMap [] lookup k (ListMap []) = Nothing lookup k (ListMap ((k', v):kvs) | k == k' = Just v | otherwise = lookup k (ListMap kvs) 适用于任何contains类型,MapLikeListMap的实例,我们可以MapLike使用contains

ListMap

面向对象的类对对象进行分类,而类型类对类进行分类。我确实认为单词ghci> let myMap = ListMap [("foo", 'a'), ("bar", b)] ghci> myMap `contains` "foo" True ghci> myMap `contains` "nabble" False class是不幸的 - 它们让具有OO背景的新人感到困惑 - 但是Haskell早于OOP变得流行,所以语言设计者不知道。 Idris,Haskell家族中的一种新语言,也有类型类,但they're called interfaces,我认为这是一个更好的名称。