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

奥列格

我的任务是实现这些功能,但我在第一个被卡住了。

为什么我不能这样写emptyghci抱怨: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)
本杰明·霍奇森

我认为您困惑的根源可能是class关键字。

忘掉你对类的所有先入为主的观念。哈斯克尔class是真的没有像class在Java这样的面向对象语言。类型类更像是 Java 而interface不是class.

更具体地说,classHaskell 中的 a 定义了类型可能符合签名接口所以当你写

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

您正在声明一个类映射类型m :: * -> * -> *,并且为了成为MapLike一个类型必须至少支持emptylookup操作。

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

contains :: (MapLike m, Ord k) => m k v -> k -> Bool
m `contains` k =
    case lookup k m of
        Just _ -> True
        Nothing -> False

类型类实现在一个instance. 你说class你正在实现哪个,你说哪个类型实现它,然后你为类中声明的函数提供一个实现。所以,在下面,我说这ListMap是一种MapLike类型,我正在解释emptylookup操作如何为该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对于任何工程MapLike类型,ListMap是的一个实例MapLike,我们可以使用contains一个ListMap

ghci> let myMap = ListMap [("foo", 'a'), ("bar", b)]
ghci> myMap `contains` "foo"
True
ghci> myMap `contains` "nabble"
False

面向对象的类对对象进行分类,而类型类对类型进行分类。我想的话classinstance不恰当-他们混淆与面向对象背景的新人-但哈斯克尔早OOP成为受欢迎的,所以语言设计师们不知道。Idris是 Haskell 家族中较新的语言,也有类型类,但它们被称为interfaces,我认为这是一个更好的名字。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章