objective 0.0 → 0.0.1
raw patch · 2 files changed
+19/−14 lines, 2 files
Files
- objective.cabal +2/−2
- src/Control/Object.hs +17/−12
objective.cabal view
@@ -2,9 +2,9 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: objective -version: 0.0 +version: 0.0.1 synopsis: Extensible objects --- description: +description: Stateful effect transducer homepage: https://github.com/fumieval/objective license: BSD3 license-file: LICENSE
src/Control/Object.hs view
@@ -8,26 +8,30 @@ import Control.Monad import Data.Typeable --- | The type 'Object e m' represents objects which can handle messages 'e', perform actions in the 'Monad' 'm'. --- It can be thought of as a function where both domain and codomain are effects. +-- | The type 'Object e m' represents objects which can handle messages 'e', perform actions in the environment 'm'. +-- It can be thought of as a function between effects. -- Thus, it can be composed just like functions using '(.>>.)' (not often needed); the identity element is `echo`. newtype Object e m = Object { runObject :: forall x. e x -> m (x, Object e m) } deriving Typeable +-- | Lift a natural transformation into an object. +liftO :: Functor f => (forall x. e x -> f x) -> Object e f +liftO f = Object $ fmap (\x -> (x, liftO f)) . f + -- | Change the workspace of the object. -transObject :: Monad n => (forall x. m x -> n x) -> Object e m -> Object e n -transObject f (Object m) = Object $ liftM (fmap (transObject f)) . f . m +transObject :: Functor g => (forall x. f x -> g x) -> Object e f -> Object e g +transObject f (Object m) = Object $ fmap (fmap (transObject f)) . f . m -- | Apply a function to the messages coming into the object. -adaptObject :: Monad m => (forall x. e x -> f x) -> Object f m -> Object e m -adaptObject f (Object m) = Object $ liftM (fmap (adaptObject f)) . m . f +adaptObject :: Functor f => (forall x. e x -> f x) -> Object f m -> Object e m +adaptObject f (Object m) = Object $ fmap (fmap (adaptObject f)) . m . f -- | Parrots messages given. echo :: Functor e => Object e e echo = Object (fmap (\x -> (x, echo))) -- | Compose two objects (aka Dependency Injection). -(.>>.) :: Monad n => Object e m -> Object m n -> Object e n -Object m .>>. Object n = Object $ \e -> liftM (\((x, m'), n') -> (x, m' .>>. n')) $ n (m e) +(.>>.) :: Functor n => Object e m -> Object m n -> Object e n +Object m .>>. Object n = Object $ \e -> fmap (\((x, m'), n') -> (x, m' .>>. n')) $ n (m e) -- | Build an object. oneshot :: (Functor e, Monad m) => (forall a. e (m a) -> m a) -> Object e m @@ -56,8 +60,9 @@ get_ = Get id put_ s = Put s () -variable :: Monad m => s -> Object (AccessT s Zero) m +-- | A mutable variable. +variable :: Applicative f => s -> Object (AccessT s Zero) f variable s = Object $ \x -> case x of - Get cont -> return (cont s, variable s) - Put s' cont -> return (cont, variable s') - LiftAccessT e -> return (extract e, variable s)+ Get cont -> pure (cont s, variable s) + Put s' cont -> pure (cont, variable s') + LiftAccessT e -> pure (extract e, variable s)