Search code examples
haskellfunctorapplicative

Why should Applicative inherit from Functor?


Indeed it does:

λ :i Applicative 
class Functor f => Applicative (f :: * -> *) where

At the same time:

fmap f x = pure f <*> x

— by the laws of Applicative we can define fmap from pure & <*>.

I don't get why I should tediously define fmap every time I want an Applicative if, really, fmap can be automatically set up in terms of pure and <*>.

I gather it would be necessary if pure or <*> were somehow dependent on the definition of fmap but I fail to see why they have to.


Solution

  • While there are proposals to make it's easier https://ghc.haskell.org/trac/ghc/wiki/IntrinsicSuperclasses the "default instances" problem itself is very difficult.

    One challenge is how to deal with common superclasses:

    fmap f x = pure f <*> x                            -- using Applicative
    fmap f x = runIdentity (traverse (Identity . f) x) -- using Traversable
    fmap f x = x >>= (return . f)               -- using Monad
    

    Which one to pick?

    So the best we can do now is to provide fmapDefault (as Data.Traversable) does; or use pure f <*> x; or fmapRep from Data.Functor.Rep when applicable.