This question has been asked before, but without a real answer. In fact the accepted answer suggests that it is not possible, despite the fact that
- StateT is a Monad, and hence a superset of Applicative. As a result, the standard libraries simply use
(<*>) = ap
- (as Petr notes) composing applicatives always yields an applicative.
One of the implementations of MaybeT I've read about used
liftA2 (<*>) :: (Applicative f, Applicative f1) => f (f1 (a -> b)) -> f (f1 a) -> f (f1 b)
to implement Applicative but I can't make that work here. My work in progress has tried lots of options around the following:
-- (<*>) :: StateT s f (a -> b) -> State s f a -> State s f b
instance (Applicative f) => Applicative (StateT s f) where
pure a = StateT $ \s -> pure (a, s)
(StateT f) <*> (StateT g) = StateT $ \s -> -- f :: s -> m (a -> b, s), g :: s -> m (a, s)
let
mabs = f s -- mabs :: m (a -> b, s)
mab = fmap fst mabs
ms' = fmap snd mabs
in undefined
I'm wondering what I am missing, and hoping that I will learn something about Applicative in the process.