diff --git a/Control/Monad/Operational/Class.hs b/Control/Monad/Operational/Class.hs
--- a/Control/Monad/Operational/Class.hs
+++ b/Control/Monad/Operational/Class.hs
@@ -1,70 +1,70 @@
-{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
-{-# LANGUAGE UndecidableInstances #-}
------------------------------------------------------------------------------
--- |
--- Module      :  Control.Monad.Operational.Class
--- Copyright   :  (C) 2012-2013 Fumiaki Kinoshita
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  Fumiaki Kinsohita <fumiexcel@gmail.com>
--- Stability   :  experimental
--- Portability :  non-portable
---
--- A class for operational monads
-----------------------------------------------------------------------------
-module Control.Monad.Operational.Class (Operational(..)) where
-
-import Control.Monad.Trans.Reader
-import qualified Control.Monad.Trans.State.Strict as Strict
-import qualified Control.Monad.Trans.State.Lazy as Lazy
-import qualified Control.Monad.Trans.Writer.Strict as Strict
-import qualified Control.Monad.Trans.Writer.Lazy as Lazy
-import qualified Control.Monad.Trans.RWS.Strict as Strict
-import qualified Control.Monad.Trans.RWS.Lazy as Lazy
-import Control.Monad.Trans.Cont
-import Control.Monad.Trans.Maybe
-import Control.Monad.Trans.List
-import Control.Monad.Trans.Error
-import Control.Monad.Trans.Identity
-import Control.Monad.Trans.Class
-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
-  singleton = lift . singleton
-
-instance (Operational f m) => Operational f (Lazy.StateT s m) where
-  singleton = lift . singleton
-
-instance (Operational f m) => Operational f (Strict.StateT s m) where
-  singleton = lift . singleton
-
-instance (Operational f m) => Operational f (ContT r m) where
-  singleton = lift . singleton
-
-instance (Operational f m, Monoid w) => Operational f (Lazy.WriterT w m) where
-  singleton = lift . singleton
-
-instance (Operational f m, Monoid w) => Operational f (Strict.WriterT w m) where
-  singleton = lift . singleton
-
-instance (Operational f m, Monoid w) => Operational f (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
-  singleton = lift . singleton
-
-instance (Operational f m) => Operational f (MaybeT m) where
-  singleton = lift . singleton
-
-instance (Operational f m) => Operational f (IdentityT m) where
-  singleton = lift . singleton
-
-instance (Operational f m) => Operational f (ListT m) where
-  singleton = lift . singleton
-
-instance (Operational f m, Error e) => Operational f (ErrorT e m) where
+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Operational.Class
+-- Copyright   :  (C) 2012-2013 Fumiaki Kinoshita
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Fumiaki Kinsohita <fumiexcel@gmail.com>
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- A class for operational monads
+----------------------------------------------------------------------------
+module Control.Monad.Operational.Class (Operational(..)) where
+
+import Control.Monad.Trans.Reader
+import qualified Control.Monad.Trans.State.Strict as Strict
+import qualified Control.Monad.Trans.State.Lazy as Lazy
+import qualified Control.Monad.Trans.Writer.Strict as Strict
+import qualified Control.Monad.Trans.Writer.Lazy as Lazy
+import qualified Control.Monad.Trans.RWS.Strict as Strict
+import qualified Control.Monad.Trans.RWS.Lazy as Lazy
+import Control.Monad.Trans.Cont
+import Control.Monad.Trans.Maybe
+import Control.Monad.Trans.List
+import Control.Monad.Trans.Error
+import Control.Monad.Trans.Identity
+import Control.Monad.Trans.Class
+import Data.Monoid
+
+class Monad m => Operational t m where -- need fundeps?
+  -- | Construct an operational action from a single imperative.
+  singleton :: t a -> m a
+
+instance (Operational f m) => Operational f (ReaderT e m) where
+  singleton = lift . singleton
+
+instance (Operational f m) => Operational f (Lazy.StateT s m) where
+  singleton = lift . singleton
+
+instance (Operational f m) => Operational f (Strict.StateT s m) where
+  singleton = lift . singleton
+
+instance (Operational f m) => Operational f (ContT r m) where
+  singleton = lift . singleton
+
+instance (Operational f m, Monoid w) => Operational f (Lazy.WriterT w m) where
+  singleton = lift . singleton
+
+instance (Operational f m, Monoid w) => Operational f (Strict.WriterT w m) where
+  singleton = lift . singleton
+
+instance (Operational f m, Monoid w) => Operational f (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
+  singleton = lift . singleton
+
+instance (Operational f m) => Operational f (MaybeT m) where
+  singleton = lift . singleton
+
+instance (Operational f m) => Operational f (IdentityT m) where
+  singleton = lift . singleton
+
+instance (Operational f m) => Operational f (ListT m) where
+  singleton = lift . singleton
+
+instance (Operational f m, Error e) => Operational f (ErrorT e m) where
   singleton = lift . singleton
diff --git a/Control/Monad/Trans/Operational/Mini.hs b/Control/Monad/Trans/Operational/Mini.hs
--- a/Control/Monad/Trans/Operational/Mini.hs
+++ b/Control/Monad/Trans/Operational/Mini.hs
@@ -1,42 +1,87 @@
-{-# 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
+{-# LANGUAGE RankNTypes, GADTs #-}
+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses,KindSignatures #-}
+-----------------------------------------------------------------------------
+-- |
+-- 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,  ReifiedProgramT(..), fromReifiedT,
+  module Control.Monad.Operational.Class
+  ) where
+
+import Control.Monad
+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
+
+
+infix 1 :>>=
+
+data ReifiedProgramT t (m :: * -> *) a where
+  Return :: a -> ReifiedProgramT t m a
+  (:>>=) :: t a -> (a -> ReifiedProgramT t m b) -> ReifiedProgramT t m b
+  Lift :: m a -> (a -> ReifiedProgramT t m b) -> ReifiedProgramT t m b
+
+fromReifiedT :: Monad m => ReifiedProgramT t m a -> ProgramT t m a
+fromReifiedT m = ProgramT $ \p i ->
+  let go (Return a) = p a
+      go (t :>>= c) = i t (go . c)
+      go (Lift a c) = a >>= go . c
+   in go m
+
+
+instance Monad m => Functor (ReifiedProgramT t m) where
+    fmap f = go where
+        go (Return a) = Return (f a)
+        go (t :>>= k) = t :>>= go . k
+        go (Lift a c) = Lift a (go.c)
+    {-# INLINE fmap #-}
+
+instance Monad m => Applicative (ReifiedProgramT t m) where
+    pure = Return
+    {-# INLINE pure #-}
+    Return f <*> Return a = Return (f a)
+    mf <*> m = mf >>= \f -> fmap f m
+
+instance Monad m => Monad (ReifiedProgramT t m) where
+    return = Return
+    {-# INLINE return #-}
+    Return a >>= f = f a
+    (t :>>= m) >>= k = t :>>= (>>= k) . m
+    Lift a c >>= f = Lift a (c >=> f)
+
+instance Monad m => Operational t (ReifiedProgramT t m) where
+    singleton t = t :>>= Return
+
+instance MonadTrans (ReifiedProgramT t) where lift = flip Lift Return
diff --git a/minioperational.cabal b/minioperational.cabal
--- a/minioperational.cabal
+++ b/minioperational.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                minioperational
-version:             0.2
+version:             0.3
 synopsis:            fast and simple operational monad
 description:         This package provides tiny implementation of operational monad.
 homepage:            https://github.com/fumieval/minioperational
