Your example is morally on the right track, but it has a few mistakes. The most obvious is that you cannot match a match from fromList ... because fromList not a constructor. Actual constructors are not exported by the Data.Map module, so we cannot match patterns at all - this means that you cannot access the internal tree view used in this module and possibly break some invariant.
A better example might be, for example, (the Ord k constraint is required by Map , as @gallais mentions)
instance Ord k => Functor (Map k) where fmap fm = fromList (map modify (toList m)) where modify (k,v) = (k, fv)
this basically turns the entire map into a list of associations consisting of key-value pairs, and then changes each value by applying f , and then restores the map back. More briefly, it can be written as
instance Ord k => Functor (Map k) where fmap f = fromList . map (\(k,v) -> (k,fv)) . toList
Keep in mind that this is not very efficient - the actual instance of the Map module should not go through an intermediate list.
Finally, note that you cannot define your own instance, since the Map module already provides it for you. If you really want to experiment with it, you can declare newtype :
newtype MyMap kv = MyMap { unMyMap :: Map kv } instance Functor (MyMap k) where fmap f = MyMap . fromList . map (\(k,v) -> (k,fv)) . toList . unMyMap
source share