Continuing the discussion from (… cont) Data.Set no Functor/Monad instance:
I threw down this code without much thought just to get something working. (I was quite surprised it worked, and even more surprised the OVERLAPPABLE
instance works smoothly.)
class Functorb (fb :: Type) where
fmapb :: fb ~ (f b) => (a -> b) -> f a -> f b
instance Ord b => Functorb (Set b) where -- with Ord b accepted
fmapb = mapSet
instance {-# OVERLAPPABLE #-} Functor f => Functorb (f b) where -- with Functor f accepted
fmapb = fmap
- in the class decl, the parameter
fb
doesn’t appear in the matrix of the method, but only in a constraint. Then - given some usage site of method
fmapb
, how does instance resolution ‘know’ which instance to select? - The class works just as well it seems (and that’s less of a surprise) with
fmapb :: fb ~ (f b) => (a -> b) -> f a -> fb -- result type is class param
- Is
~
so magic that the method sig I first wrote is interpreted as the second?