Question

Are there any good examples of Functors which are not Applicatives? By good, I'm seeking non-trivial (not Const Void) examples which don't need appeals to undefined. If there are none is there any method of proving that the space there is uninteresting?

This is similar to Good examples of Not a Functor/Functor/Applicative/Monad?, but it wasn't completely resolved there.

As a follow-up question, are there any interesting examples of Functors which might be left without Applicative instances due to having far too many non-canonical Applicative instances to be meaningful? For instance, "extended Maybe" is a bit boring

data MayB a = Jus a | Nothing1 | Nothing2 | Nothing3 | ...

instance Applicative MayB where
  pure = Jus
  Jus f <*> Jus x = Jus (f x)
  Jus f <*> n     = n
  n     <*> Jus x = n
  n1    <*> n2    = methodOfResolvingNothingWhatsoever n1 n2

Are there examples where the variations of the Applicative instance are more material?

Was it helpful?

Solution

The main place where I see functor but not applicatives is in large product types. Consider something like

 data Mean where
    Unfair :: Monad a => a () -> Mean
 data Foo a = Bar Int Mean a

This is easily a functor, but there's no way to make this an applicative because

 (Bar i g f) (Bar i' g' a) = Bar ??? ??? (f a)

We can only fill in our ???s with something that's a monoid-like in at least one way and Mean never is since we have no way of specifying something to combine two values of arbitrary types g :: a and g' :: b in an associative way.

Additionally, we need the mempty or something like it for pure :: a -> f a. We're given an a so most of the data type that involves an a is trivial to construct, but the rest needs a sane "empty" value.

So if we smashed applicative and functor into one large type class, most of lens would fall apart because most of the useful cases for lens involve situations just like these, where there isn't a sane Applicative instance.

So to put this in a hand-wavey squishy way: When there's a lot of "stuff" in a type that isn't directly to do with the type parameter applicative is defined over, we need a way to merge all of this "stuff" which isn't always possible.

OTHER TIPS

A very important (if unfair) example is

{-# LANGUAGE ExistentialQuantification #-}

data AFunctor a = forall f . Functor f => AFunctor { unFunct :: f a }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top