{-# LANGUAGE GADTs #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-| Module: Control.Remote.Applicative Copyright: (C) 2016, The University of Kansas License: BSD-style (see the file LICENSE) Maintainer: Andy Gill Stability: Alpha Portability: GHC -} 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) -> fmap 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 -- This improves our bundling opportunities 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)