packages feed

minioperational 0.3 → 0.4

raw patch · 5 files changed

+91/−24 lines, 5 filesdep +template-haskellPVP ok

version bump matches the API change (PVP)

Dependencies added: template-haskell

API changes (from Hackage documentation)

- Control.Monad.Operational.Class: class Monad m => Operational t m
- Control.Monad.Operational.Class: instance (Operational f m, Error e) => Operational f (ErrorT e m)
- Control.Monad.Operational.Class: instance (Operational f m, Monoid w) => Operational f (RWST r w s m)
- Control.Monad.Operational.Class: instance (Operational f m, Monoid w) => Operational f (WriterT w m)
- Control.Monad.Operational.Class: instance Operational f m => Operational f (ContT r m)
- Control.Monad.Operational.Class: instance Operational f m => Operational f (IdentityT m)
- Control.Monad.Operational.Class: instance Operational f m => Operational f (ListT m)
- Control.Monad.Operational.Class: instance Operational f m => Operational f (MaybeT m)
- Control.Monad.Operational.Class: instance Operational f m => Operational f (ReaderT e m)
- Control.Monad.Operational.Class: instance Operational f m => Operational f (StateT s m)
- Control.Monad.Operational.Mini: instance Operational t (Program t)
- Control.Monad.Operational.Mini: instance Operational t (ReifiedProgram t)
- Control.Monad.Trans.Operational.Mini: instance Monad m => Operational t (ReifiedProgramT t m)
- Control.Monad.Trans.Operational.Mini: instance Operational t (ProgramT t m)
+ Control.Monad.Operational.Class: class Monad m => (:!) t m | m -> t
+ Control.Monad.Operational.Class: instance (t :! m, Error e) => t :! ErrorT e m
+ Control.Monad.Operational.Class: instance (t :! m, Monoid w) => t :! RWST r w s m
+ Control.Monad.Operational.Class: instance (t :! m, Monoid w) => t :! WriterT w m
+ Control.Monad.Operational.Class: instance t :! m => t :! ContT r m
+ Control.Monad.Operational.Class: instance t :! m => t :! IdentityT m
+ Control.Monad.Operational.Class: instance t :! m => t :! ListT m
+ Control.Monad.Operational.Class: instance t :! m => t :! MaybeT m
+ Control.Monad.Operational.Class: instance t :! m => t :! ReaderT e m
+ Control.Monad.Operational.Class: instance t :! m => t :! StateT s m
+ Control.Monad.Operational.Mini: instance t :! Program t
+ Control.Monad.Operational.Mini: instance t :! ReifiedProgram t
+ Control.Monad.Operational.TH: makeSingletons :: Name -> Q [Dec]
+ Control.Monad.Trans.Operational.Mini: instance Monad m => t :! ReifiedProgramT t m
+ Control.Monad.Trans.Operational.Mini: instance t :! ProgramT t m
- Control.Monad.Operational.Class: singleton :: Operational t m => t a -> m a
+ Control.Monad.Operational.Class: singleton :: :! t m => t a -> m a
- Control.Monad.Operational.Mini: cloneProgram :: Operational t m => Program t a -> m a
+ Control.Monad.Operational.Mini: cloneProgram :: t :! m => Program t a -> m a

Files

Control/Monad/Operational/Class.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} ----------------------------------------------------------------------------- -- |@@ -12,7 +12,7 @@ -- -- A class for operational monads -----------------------------------------------------------------------------module Control.Monad.Operational.Class (Operational(..)) where+module Control.Monad.Operational.Class ((:!)(..)) where  import Control.Monad.Trans.Reader import qualified Control.Monad.Trans.State.Strict as Strict@@ -29,42 +29,42 @@ import Control.Monad.Trans.Class import Data.Monoid -class Monad m => Operational t m where -- need fundeps?+class Monad m => 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+instance (t :! m) => t :! ReaderT e m where   singleton = lift . singleton -instance (Operational f m) => Operational f (Lazy.StateT s m) where+instance (t :! m) => t :! Lazy.StateT s m where   singleton = lift . singleton -instance (Operational f m) => Operational f (Strict.StateT s m) where+instance (t :! m) => t :! Strict.StateT s m where   singleton = lift . singleton -instance (Operational f m) => Operational f (ContT r m) where+instance (t :! m) => t :! ContT r m where   singleton = lift . singleton -instance (Operational f m, Monoid w) => Operational f (Lazy.WriterT w m) where+instance (t :! m, Monoid w) => t :! Lazy.WriterT w m where   singleton = lift . singleton -instance (Operational f m, Monoid w) => Operational f (Strict.WriterT w m) where+instance (t :! m, Monoid w) => t :! Strict.WriterT w m where   singleton = lift . singleton -instance (Operational f m, Monoid w) => Operational f (Strict.RWST r w s m) where+instance (t :! m, Monoid w) => t :! Strict.RWST r w s m where   singleton = lift . singleton -instance (Operational f m, Monoid w) => Operational f (Lazy.RWST r w s m) where+instance (t :! m, Monoid w) => t :! Lazy.RWST r w s m where   singleton = lift . singleton -instance (Operational f m) => Operational f (MaybeT m) where+instance (t :! m) => t :! MaybeT m where   singleton = lift . singleton -instance (Operational f m) => Operational f (IdentityT m) where+instance (t :! m) => t :! IdentityT m where   singleton = lift . singleton -instance (Operational f m) => Operational f (ListT m) where+instance (t :! m) => t :! ListT m where   singleton = lift . singleton -instance (Operational f m, Error e) => Operational f (ErrorT e m) where+instance (t :! m, Error e) => t :! ErrorT e m where   singleton = lift . singleton
Control/Monad/Operational/Mini.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE RankNTypes, FlexibleInstances, MultiParamTypeClasses, GADTs #-}
+{-# LANGUAGE RankNTypes, FlexibleInstances, MultiParamTypeClasses, GADTs, TypeOperators #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Operational.Mini
@@ -42,10 +42,10 @@ interpret :: Monad m => (forall x. t x -> m x) -> Program t a -> m a
 interpret e (Program m) = m return (\t f -> e t >>= f)
 
-cloneProgram :: Operational t m => Program t a -> m a
+cloneProgram :: (t :! m) => Program t a -> m a
 cloneProgram (Program m) = m return (\t c -> singleton t >>= c)
 
-instance Operational t (Program t) where
+instance t :! Program t where
     singleton t = Program $ \p i -> i t p
 
 -- | Reified version of 'Program'. It is useful for testing.
@@ -76,5 +76,5 @@     Return a >>= f = f a
     (t :>>= m) >>= k = t :>>= (>>= k) . m
 
-instance Operational t (ReifiedProgram t) where
+instance t :! ReifiedProgram t where
     singleton t = t :>>= Return
+ Control/Monad/Operational/TH.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE TemplateHaskell #-}
+module Control.Monad.Operational.TH (makeSingletons) where
+
+import Language.Haskell.TH
+import Control.Monad.Operational.Class
+import Data.Char
+
+import Control.Monad.Trans.State
+import Control.Applicative
+import Data.List (union)
+import Data.Maybe (fromJust)
+
+renameType :: [(Name, Name)] -> Type -> State Int Type
+renameType m (VarT n) = case n `lookup` m of
+    Just n' -> return $ VarT n'
+    Nothing -> do
+        i <- get
+        modify (+1)
+        return $ VarT $ mkName $ "a" ++ show i
+renameType m (SigT t k)          = SigT <$> renameType m t <*> pure k
+renameType m (AppT l r)          = AppT <$> renameType m l <*> renameType m r
+renameType _ t                   = pure t
+
+tyVars :: Type -> [Name]
+tyVars (VarT n) = [n]
+tyVars (AppT l r) = tyVars l ++ tyVars r
+tyVars _ = []
+
+makeSingletons :: Name -> Q [Dec]
+makeSingletons name = do
+    TyConI dec <- reify name
+    case dec of
+        DataD _ _ vs cs _ -> fmap concat $ mapM (fromCon (map fromTyVarBndr vs)) cs
+        _ -> fail "Expecting a type construcor"
+    where
+        gen vs conName argTypes resultType = do
+            let bodyName = let (b:bs) = nameBase name in mkName (toLower b : bs)
+                ref = [(n, mkName ("p" ++ show i)) | (i, n) <- zip [(0::Int)..] (init vs)]
+                instr = foldl AppT (ConT name) $ map VarT $ map (fromJust . (`lookup`ref)) (init vs)
+                
+                m = mkName "m"
+                
+                ts = evalState (mapM (renameType ref) argTypes) 0
+                result = evalState (renameType ref resultType) 0
+                
+                vars = PlainTV m : map PlainTV (map snd ref `union` tyVars result)
+                
+                sig = SigD bodyName $ ForallT vars [ClassP ''(:!) [instr, VarT m]]
+                    $ foldr (\x y -> AppT ArrowT x `AppT` y) (AppT (VarT m) result) ts
+            
+            ps <- mapM (newName . ("p"++) . show) [0..length argTypes - 1]
+
+            let body = AppE (VarE 'singleton) $ foldl AppE (ConE conName) (map VarE ps)
+
+            return [sig, FunD bodyName [Clause (map VarP ps) (NormalB body) []]]  
+
+        fromCon vs (ForallC _ [EqualP _ t] (NormalC conName ts)) = gen vs conName (map snd ts) t
+        fromCon vs (NormalC conName ts) = gen vs conName (map snd ts) (VarT $ last vs)
+        fromCon _ _ = fail "Unsupported data constructor"
+
+        fromTyVarBndr :: TyVarBndr -> Name
+        fromTyVarBndr (PlainTV n) = n
+        fromTyVarBndr (KindedTV n _) = n
Control/Monad/Trans/Operational/Mini.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE RankNTypes, GADTs #-}+{-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses,KindSignatures #-} ----------------------------------------------------------------------------- -- |@@ -39,7 +40,7 @@ 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+instance t :! ProgramT t m where     singleton t = ProgramT $ \p i -> i t p  instance MonadTrans (ProgramT t) where@@ -81,7 +82,7 @@     (t :>>= m) >>= k = t :>>= (>>= k) . m     Lift a c >>= f = Lift a (c >=> f) -instance Monad m => Operational t (ReifiedProgramT t m) where+instance Monad m => t :! ReifiedProgramT t m where     singleton t = t :>>= Return  instance MonadTrans (ReifiedProgramT t) where lift = flip Lift Return
minioperational.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                minioperational
-version:             0.3
+version:             0.4
 synopsis:            fast and simple operational monad
 description:         This package provides tiny implementation of operational monad.
 homepage:            https://github.com/fumieval/minioperational
@@ -22,6 +22,9 @@ library
   default-language:   Haskell2010
   ghc-options: -Wall -O2
-  exposed-modules:     Control.Monad.Operational.Mini, Control.Monad.Trans.Operational.Mini, Control.Monad.Operational.Class
+  exposed-modules:     Control.Monad.Operational.Mini
+    , Control.Monad.Trans.Operational.Mini
+    , Control.Monad.Operational.Class
+    , Control.Monad.Operational.TH
   -- other-modules:       
-  build-depends:       base ==4.*, transformers >= 0.2.0 && <0.4+  build-depends:       base ==4.*, transformers >= 0.2.0 && <0.4, template-haskell