module Control.Remote.Monad.Packet.Applicative
(
ApplicativePacket(..)
, superCommand
) where
import Control.Monad.Trans.Class
import Control.Monad.Trans.State.Strict
import qualified Control.Remote.Monad.Packet.Strong as Strong
import Control.Natural
data ApplicativePacket (c :: *) (p :: * -> *) (a :: *) where
Command :: ApplicativePacket c p b -> c -> ApplicativePacket c p b
Procedure :: ApplicativePacket c p (a -> b) -> p a -> ApplicativePacket c p b
Pure :: a -> ApplicativePacket c p a
instance Functor (ApplicativePacket c p) where
fmap f (Command g c) = Command (fmap f g) c
fmap f (Procedure g p) = Procedure (fmap (f .) g) p
fmap f (Pure a) = Pure (f a)
instance Applicative (ApplicativePacket c p) where
pure a = Pure a
(Pure f) <*> m = fmap f m
(Command g c) <*> (Pure a) = Command (fmap (\ f -> f a) g) c
(Procedure g p) <*> (Pure a) = Procedure (fmap (\ f a1 -> f a1 a) g) p
m <*> (Command g2 c2) = Command (m <*> g2) c2
m <*> (Procedure g2 p2) = Procedure (fmap (.) m <*> g2) p2
superCommand :: ApplicativePacket c p a -> Maybe a
superCommand (Pure a) = Just a
superCommand (Command g _) = superCommand g
superCommand (Procedure _ _) = Nothing