module Control.Remote.Monad.Types
( RemoteMonad(..)
, RemoteApplicative(..)
) where
import Control.Remote.Monad.Packet.Applicative
import Control.Natural
data RemoteMonad c p a where
Appl :: RemoteApplicative c p a -> RemoteMonad c p a
Bind :: RemoteApplicative c p a -> (a -> RemoteMonad c p b) -> RemoteMonad c p b
instance Functor (RemoteMonad c p) where
fmap f m = pure f <*> m
instance Applicative (RemoteMonad c p) where
pure a = Appl (pure a)
Appl f <*> Appl g = Appl (f <*> g)
Appl f <*> Bind m k = Bind (pure (,) <*> f <*> m) (\ (a,b) -> pure a <*> k b)
Bind m k <*> r = Bind m (\ a -> k a <*> r)
Appl f *> Appl g = Appl (f *> g)
Appl f *> Bind m k = Bind (f *> m) k
Bind m k *> r = Bind m (\ a -> k a *> r)
Appl f <* Appl g = Appl (f <* g)
Appl f <* Bind m k = Bind (pure (,) <*> f <*> m) (\ (a,b) -> pure a <* k b)
Bind m k <* r = Bind m (\ a -> k a <* r)
instance Monad (RemoteMonad c p) where
return = pure
Appl m >>= k = Bind m k
Bind m k >>= k2 = Bind m (\ a -> k a >>= k2)
m1 >> m2 = m1 *> m2
newtype RemoteApplicative c p a = RemoteApplicative (ApplicativePacket c p a)
instance Functor (RemoteApplicative c p) where
fmap f (RemoteApplicative g) = RemoteApplicative (fmap f g)
instance Applicative (RemoteApplicative c p) where
pure a = RemoteApplicative (pure a)
(RemoteApplicative f) <*> (RemoteApplicative g) = RemoteApplicative (f <*> g)