我的任务是实现这些功能,但我在第一个被卡住了。
为什么我不能这样写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)
我认为您困惑的根源可能是class
关键字。
忘掉你对类的所有先入为主的观念。哈斯克尔class
是真的没有像class
在Java这样的面向对象语言。类型类更像是 Java 而interface
不是class
.
更具体地说,class
Haskell 中的 a 定义了类型可能符合的签名或接口。所以当你写
class MapLike m where
empty :: m k v
lookup :: Ord k => k -> m k v -> Maybe v
您正在声明一个类映射类型m :: * -> * -> *
,并且为了成为MapLike
一个类型必须至少支持empty
和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
. 你说class
你正在实现哪个,你说哪个类型实现它,然后你为类中声明的函数提供一个实现。所以,在下面,我说这ListMap
是一种MapLike
类型,我正在解释empty
和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
对于任何工程MapLike
类型,ListMap
是的一个实例MapLike
,我们可以使用contains
一个ListMap
。
ghci> let myMap = ListMap [("foo", 'a'), ("bar", b)]
ghci> myMap `contains` "foo"
True
ghci> myMap `contains` "nabble"
False
面向对象的类对对象进行分类,而类型类对类型进行分类。我想的话class
和instance
不恰当-他们混淆与面向对象背景的新人-但哈斯克尔早OOP成为受欢迎的,所以语言设计师们不知道。Idris是 Haskell 家族中较新的语言,也有类型类,但它们被称为interface
s,我认为这是一个更好的名字。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句