I am trying to figure out how to properly define Applicative for the type
data (:*:) p q u v = (:*:) {pfst :: p u v, psnd :: q u v} deriving (Show, Eq, Functor)
I currently have Applicative, Monad, and MonadFail defined as
instance (Applicative (p u), Applicative (q u)) => Applicative ((:*:) p q u) where
pure x = pure x :*: pure x
(f :*: b) <*> (f' :*: b') = (f <*> f') :*: (b <*> b')
instance (Monad (p u), Monad (q u)) => Monad ((:*:) p q u) where
(fw :*: bw) >>= f = (fw >>= pfst . f) :*: (bw >>= psnd . f)
instance (MonadFail (p u), MonadFail (q u)) => MonadFail ((:*:) p q u) where
fail msg = fail msg :*: fail msg
This seems to work ok until I recursively use Applicative. For example
x :: (ConstM Maybe :*: ConstM Maybe) () ()
x = fail "" *> x
y :: (ConstM Maybe :*: ConstM Maybe) () ()
y = fail "" >> y
newtype ConstM m p a = ConstM (m a) deriving (Show, Eq, Functor, Applicative, Monad, MonadFail)
The Applicative x
will never finish while Monadic y
will. Is there a way to define <*>
so this can complete?