minioperational 0.1 → 0.2
raw patch · 4 files changed
+110/−13 lines, 4 filesdep −freedep −kan-extensionsPVP ok
version bump matches the API change (PVP)
Dependencies removed: free, kan-extensions
API changes (from Hackage documentation)
- Control.Monad.Operational.Mini: type Program t = F (Yoneda t)
+ Control.Monad.Operational.Mini: (:>>=) :: t a -> (a -> ReifiedProgram t b) -> ReifiedProgram t b
+ Control.Monad.Operational.Mini: Program :: (forall r. (a -> r) -> (forall x. t x -> (x -> r) -> r) -> r) -> Program t a
+ Control.Monad.Operational.Mini: Return :: a -> ReifiedProgram t a
+ Control.Monad.Operational.Mini: cloneProgram :: Operational t m => Program t a -> m a
+ Control.Monad.Operational.Mini: data ReifiedProgram t a
+ Control.Monad.Operational.Mini: fromReified :: ReifiedProgram t a -> Program t a
+ Control.Monad.Operational.Mini: instance Applicative (Program t)
+ Control.Monad.Operational.Mini: instance Applicative (ReifiedProgram t)
+ Control.Monad.Operational.Mini: instance Functor (Program t)
+ Control.Monad.Operational.Mini: instance Functor (ReifiedProgram t)
+ Control.Monad.Operational.Mini: instance Monad (Program t)
+ Control.Monad.Operational.Mini: instance Monad (ReifiedProgram t)
+ Control.Monad.Operational.Mini: instance Operational t (ReifiedProgram t)
+ Control.Monad.Operational.Mini: newtype Program t a
+ Control.Monad.Operational.Mini: unProgram :: Program t a -> forall r. (a -> r) -> (forall x. t x -> (x -> r) -> r) -> r
+ Control.Monad.Trans.Operational.Mini: ProgramT :: (forall r. (a -> m r) -> (forall x. t x -> (x -> m r) -> m r) -> m r) -> ProgramT t m a
+ Control.Monad.Trans.Operational.Mini: instance Applicative (ProgramT t m)
+ Control.Monad.Trans.Operational.Mini: instance Functor (ProgramT t m)
+ Control.Monad.Trans.Operational.Mini: instance Monad (ProgramT t m)
+ Control.Monad.Trans.Operational.Mini: instance MonadTrans (ProgramT t)
+ Control.Monad.Trans.Operational.Mini: instance Operational t (ProgramT t m)
+ Control.Monad.Trans.Operational.Mini: interpret :: Monad m => (forall x. t x -> m x) -> ProgramT t m a -> m a
+ Control.Monad.Trans.Operational.Mini: newtype ProgramT t m a
+ Control.Monad.Trans.Operational.Mini: unProgram :: ProgramT t m a -> forall r. (a -> m r) -> (forall x. t x -> (x -> m r) -> m r) -> m r
Files
- Control/Monad/Operational/Class.hs +1/−0
- Control/Monad/Operational/Mini.hs +64/−10
- Control/Monad/Trans/Operational/Mini.hs +42/−0
- minioperational.cabal +3/−3
Control/Monad/Operational/Class.hs view
@@ -30,6 +30,7 @@ import Data.Monoid class Monad m => Operational t m | m -> t where + -- | Construct an operational action from a single imperative. singleton :: t a -> m a instance (Operational f m) => Operational f (ReaderT e m) where
Control/Monad/Operational/Mini.hs view
@@ -1,26 +1,80 @@-{-# LANGUAGE Rank2Types, GADTs, TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses #-} +{-# LANGUAGE RankNTypes, FlexibleInstances, MultiParamTypeClasses, GADTs #-} ----------------------------------------------------------------------------- -- | -- Module : Control.Monad.Operational.Mini -- Copyright : (C) 2012-2013 Fumiaki Kinoshita -- License : BSD-style (see the file LICENSE) -- --- Maintainer : Fumiaki Kinsohita <fumiexcel@gmail.com> +-- Maintainer : Fumiaki Kinoshita <fumiexcel@gmail.com> -- Stability : experimental --- Portability : non-portable +-- Portability : RankNTypes -- --- Simple operational monad from a free monad +-- Simple operational monad ---------------------------------------------------------------------------- -module Control.Monad.Operational.Mini (Program, interpret, module Control.Monad.Operational.Class) where +module Control.Monad.Operational.Mini (Program(..) + , interpret + , cloneProgram + , ReifiedProgram(..) + , fromReified + , module Control.Monad.Operational.Class) where -import Data.Functor.Yoneda.Contravariant -import Control.Monad.Free.Church import Control.Monad.Operational.Class +import Control.Applicative -type Program t = F (Yoneda t) +infixl 1 :>>= +-- | Program t is a 'Monad' that represents a sequence of imperatives. +-- To construct imperatives, use 'singleton' :: t a -> Program t a. +newtype Program t a = Program { unProgram :: forall r. (a -> r) -> (forall x. t x -> (x -> r) -> r) -> r } + +instance Functor (Program t) where + fmap f (Program m) = Program $ \p i -> m (p . f) i + +instance Applicative (Program t) where + pure a = Program $ \p _ -> p a + Program mf <*> Program ma = Program $ \p i -> mf (\f -> ma (p . f) i) i + +instance Monad (Program t) where + return a = Program $ \p _ -> p a + Program m >>= k = Program $ \p i -> m (\a -> unProgram (k a) p i) i + +-- | Interpret a 'Program' using the given transformation. interpret :: Monad m => (forall x. t x -> m x) -> Program t a -> m a -interpret e (F m) = m return (\(Yoneda f t) -> e t >>= f) +interpret e (Program m) = m return (\t f -> e t >>= f) +cloneProgram :: Operational t m => Program t a -> m a +cloneProgram (Program m) = m return (\t c -> singleton t >>= c) + instance Operational t (Program t) where - singleton = liftF . liftYoneda+ singleton t = Program $ \p i -> i t p + +-- | Reified version of 'Program'. It is useful for testing. +data ReifiedProgram t a where + Return :: a -> ReifiedProgram t a + (:>>=) :: t a -> (a -> ReifiedProgram t b) -> ReifiedProgram t b + +fromReified :: ReifiedProgram t a -> Program t a +fromReified m = Program $ \p i -> + let go (Return a) = p a + go (t :>>= c) = i t (go . c) in go m + +instance Functor (ReifiedProgram t) where + fmap f = go where + go (Return a) = Return (f a) + go (t :>>= k) = t :>>= go . k + {-# INLINE fmap #-} + +instance Applicative (ReifiedProgram t) where + pure = Return + {-# INLINE pure #-} + Return f <*> Return a = Return (f a) + mf <*> m = mf >>= \f -> fmap f m + +instance Monad (ReifiedProgram t) where + return = Return + {-# INLINE return #-} + Return a >>= f = f a + (t :>>= m) >>= k = t :>>= (>>= k) . m + +instance Operational t (ReifiedProgram t) where + singleton t = t :>>= Return
+ Control/Monad/Trans/Operational/Mini.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE RankNTypes, GADTs #-} +{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} +----------------------------------------------------------------------------- +-- | +-- Module : Control.Monad.Trans.Operational.Mini +-- Copyright : (C) 2013 Fumiaki Kinoshita +-- License : BSD-style (see the file LICENSE) +-- +-- Maintainer : Fumiaki Kinoshita <fumiexcel@gmail.com> +-- Stability : experimental +-- Portability : RankNTypes +-- +-- Simple operational monad transformer +---------------------------------------------------------------------------- +module Control.Monad.Trans.Operational.Mini (ProgramT(..), interpret, module Control.Monad.Operational.Class) where + +import Control.Monad.Operational.Class +import Control.Applicative +import Control.Monad.Trans.Class + +newtype ProgramT t m a = ProgramT { unProgram :: forall r. (a -> m r) -> (forall x. t x -> (x -> m r) -> m r) -> m r } + +instance Functor (ProgramT t m) where + fmap f (ProgramT m) = ProgramT $ \p i -> m (p . f) i + +instance Applicative (ProgramT t m) where + pure a = ProgramT $ \p _ -> p a + ProgramT mf <*> ProgramT ma = ProgramT $ \p i -> mf (\f -> ma (p . f) i) i + +instance Monad (ProgramT t m) where + return a = ProgramT $ \p _ -> p a + ProgramT m >>= k = ProgramT $ \p i -> m (\a -> unProgram (k a) p i) i + +-- | Interpret a 'Program' using the given transformation. +interpret :: Monad m => (forall x. t x -> m x) -> ProgramT t m a -> m a +interpret e (ProgramT m) = m return (\t c -> e t >>= c) + +instance Operational t (ProgramT t m) where + singleton t = ProgramT $ \p i -> i t p + +instance MonadTrans (ProgramT t) where + lift m = ProgramT $ \p _ -> m >>= p
minioperational.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: minioperational -version: 0.1 +version: 0.2 synopsis: fast and simple operational monad description: This package provides tiny implementation of operational monad. homepage: https://github.com/fumieval/minioperational @@ -22,6 +22,6 @@ library default-language: Haskell2010 ghc-options: -Wall -O2 - exposed-modules: Control.Monad.Operational.Mini, Control.Monad.Operational.Class + exposed-modules: Control.Monad.Operational.Mini, Control.Monad.Trans.Operational.Mini, Control.Monad.Operational.Class -- other-modules: - build-depends: base ==4.*, kan-extensions ==3.*, free ==3.*, transformers >= 0.2.0 && <0.4+ build-depends: base ==4.*, transformers >= 0.2.0 && <0.4