Are there any good examples of Functor
s which are not Applicative
s? 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 Functor
s 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?
As I understand, every monad is a functor but not every functor is a monad. A functor takes a pure function (and a functorial value) whereas a monad takes a Kleisli arrow, i.e. a function that returns a monad (and a monadic value).
The expression fmap (*2) is a function that takes a functor f over numbers and returns a functor over numbers. That functor can be a list, a Maybe , an Either String, whatever. The expression fmap (replicate 3) will take a functor over any type and return a functor over a list of elements of that type.
The functor laws express that a translation of functions preserves the structure of how the functions compose, in addition to preserving the structure of the containers. Mapping a set doesn't preserve those structures, and that's the reason that sets aren't functors.
Functors and monoids were both wrappers around a value that allow us to execute operations on them. In the case of functors it was map in the case of monoids it was compose , where compose is a single operation. Now monads. Monad's are both a functor and a monoid.
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.
A very important (if unfair) example is
{-# LANGUAGE ExistentialQuantification #-}
data AFunctor a = forall f . Functor f => AFunctor { unFunct :: f a }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With