So I have this class:
class Collection c where
empty :: c key value
singleton :: key -> value -> c key value
insert :: Ord key => key -> value -> c key value -> c key value
looKup :: Ord key => key -> c key value -> Maybe value
delete :: Ord key => key -> c key value -> c key value
keys :: c key value -> [key]
keys x = map fst $ toList x
values :: c key value -> [value]
values c = map snd $ toList c
toList :: c key value -> [(key, value)]
fromList :: Ord key => [(key,value)] -> c key value
fromList [] = empty
fromList ((k, v):xs) = insert k v (fromList xs)
Why is this
instance Collection (PairList k v) where
a bad instantion of the class and this:
instance Collection PairList where
is a good one ?
I know that when making maybe an instance of Eq, this is how haskell does it:
instance Eq (Maybe m) where
Just x == Just y = x == y
Nothing == Nothing = True
_ == _ = False
So instantiations accept parameters... So why is the first one like so ?
CodePudding user response:
Based on how c is used, Collection requires something of kind * -> * -> *.
> :k Collection
Collection :: (* -> * -> *) -> Constraint
PairList k v, though, has kind *.
Eq, on the other hand, expects something of kind *, which is exactly what Maybe m is.
> :k Eq
Eq :: * -> Constraint
(Maybe itself has kind * -> *, but applying it to a type variable produces something of kind *.)
CodePudding user response:
The thing you put in the instance head will be substituted for the class variable everywhere. So, if we combine
class Collection c where
empty :: c key value
-- and other stuff, too, of course
and
instance Collection (PairList k v)
we get the type
empty :: (PairList k v) key value
which doesn't make a lot of sense. But if we combine the class declaration with
instance Collection PairList
then we get the type
empty :: PairList key value
which makes sense just fine.
