As described this question/answers, Functor
instances are uniquely determined, if they exists.
For lists, there are two well know Applicative instances: []
and ZipList
. So Applicative isn't unique (see also Can GHC derive Functor and Applicative instances for a monad transformer? and Why is there no -XDeriveApplicative
extension?). However, ZipList
needs infinite lists, as its pure
repeats a given element indefinitely.
Applicative
instances?Going further, if we could extend both []
and ZipList
to a Monad, we'd have an example where a monad isn't uniquely determined by the data type and its Functor. Alas, ZipList
has a Monad instance only if we restrict ourselves to infinite lists (streams). And return
for []
creates a single-element list, so it requires finite lists. Therefore:
In the case there is an example with two or more distinct instances, an obvious question arises, if they must/can have the same Applicative instance:
And finally we can ask the same question for Alternative/MonadPlus. This is complicated by the fact that there are two distinct set of MonadPlus laws. Assuming we accept one of the set of laws (and for Applicative we accept right/left distributivity/absorption, see also this question),
If any of the above are unique, I'd be interested in knowing why, to have a hint of a proof. If not, an counter-example.
An applicative is a data type that implements the Applicative typeclass. A monad is a data type that implements the Monad typeclass. A Maybe implements all three, so it is a functor, an applicative, and a monad.
Monads are not a replacement for applicative functors Instead, every monad is an applicative functor (as well as a functor). It is considered good practice not to use >>= if all you need is <*>, or even fmap.
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).
First, since Monoid
s are not unique, neither are Writer
Monad
s or Applicative
s. Consider
data M a = M Int a
then you can give it Applicative
and Monad
instances isomorphic to either of:
Writer (Sum Int) Writer (Product Int)
Given a Monoid
instance for a type s
, another isomorphic pair with different Applicative
/Monad
instances is:
ReaderT s (Writer s) State s
As for having one Applicative
instance extend to two different Monad
s, I cannot remember any example. However, back when I tried to convince myself completely about whether ZipList
really cannot be made a Monad
, I found the following pretty strong restriction that holds for any Monad
:
join (fmap (\x -> fmap (\y -> f x y) ys) xs) = f <$> xs <*> ys
That doesn't give join
for all values though: in the case of lists the restricted values are the ones where all elements have the same length, i.e. lists of lists with "rectangular" shape.
(For Reader
monads, where the "shape" of monadic values doesn't vary, these are in fact all the m (m x)
values, so those do have unique extension. EDIT: Come to think of it, Either
, Maybe
and Writer
also have only "rectangular" m (m x)
values, so their extension from Applicative
to Monad
is also unique.)
I wouldn't be surprised if an Applicative
with two Monad
s exists, though.
For Alternative
/MonadPlus
, I cannot recall any law for instances using the Left Distribution law instead of Left Catch, I see nothing preventing you from just swapping (<|>)
with flip (<|>)
. I don't know if there's a less trivial variation.
ADDENDUM: I suddenly remembered I had found an example of an Applicative
with two Monad
s. Namely, finite lists. There's the usual Monad []
instance, but you can then replace its join
by the following function (essentially making empty lists "infectious"):
ljoin xs | any null xs = [] | otherwise = concat xs
(Alas, the lists need to be finite because otherwise the null
check will never finish, and that would ruin the join . fmap return == id
monad law.)
This has the same value as join
/concat
on rectangular lists of lists, so will give the same Applicative
. As I recall, it turns out that the first two monad laws are automatic from that, and you just need to check ljoin . ljoin == ljoin . fmap ljoin
.
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