diff --git a/objective.cabal b/objective.cabal
--- a/objective.cabal
+++ b/objective.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                objective
-version:             0.3
+version:             0.4
 synopsis:            Extensible objects
 description:         Stateful effect transducer
 homepage:            https://github.com/fumieval/objective
@@ -20,6 +20,7 @@
   exposed-modules:     Control.Object, Control.Monad.Objective.Class, Control.Monad.Objective.IO, Control.Monad.Objective
   -- other-modules:       
   other-extensions:    MultiParamTypeClasses, KindSignatures, TypeFamilies
-  build-depends:       base >=4.5 && <5, trivia, comonad, transformers >= 0.3 && <0.5, free >= 4.0 && <5
+  build-depends:       base >=4.5 && <5, transformers >= 0.3 && <0.5, free >= 4.0 && <5, clean-unions < 0.2
+  ghc-options: -Wall
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/src/Control/Monad/Objective/Class.hs b/src/Control/Monad/Objective/Class.hs
--- a/src/Control/Monad/Objective/Class.hs
+++ b/src/Control/Monad/Objective/Class.hs
@@ -1,6 +1,8 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE CPP #-}
 
 module Control.Monad.Objective.Class where
@@ -26,9 +28,12 @@
 import Data.Monoid
 import Control.Monad
 import Control.Monad.Free
+import Data.OpenUnion1.Clean
 
 infix 3 .-
 infix 3 .&
+infix 3 .|-
+infix 3 .^>
 
 class Monad m => MonadObjective m where
 
@@ -40,12 +45,7 @@
   -- | Add an object to the environment.
   new :: Object e (Residence m) -> m (Address e m)
 
--- | Old synonym for 'new'.
-invoke :: MonadObjective m => Object e (Residence m) -> m (Address e m)
-invoke = new
-{-# DEPRECATED invoke "Use new instead of misleading invoke" #-} 
-
-(.&) :: (MonadObjective m, Stateful s e) => Address e m -> Strict.StateT s m a -> m a
+(.&) :: (MonadObjective m, Lift (Strict.State s) f) => Address f m -> Strict.StateT s m a -> m a
 c .& m = do
   s <- c .- get_
   (a, s') <- Strict.runStateT m s
@@ -56,6 +56,12 @@
 (.|-) :: MonadObjective m => Address e m -> Free e a -> m a
 _ .|- Pure a = return a
 c .|- Free f = c .- f >>= (c .|-)
+
+(.^>) :: (MonadObjective m, f ∈ u) => Address (Union u) m -> f a -> m a
+c .^> f = c .- liftU f
+
+(.<<) :: (MonadObjective m, Lift (Request a b) f) => Address f m -> a -> m b 
+c .<< a = c .- request a
 
 instance MonadObjective m => MonadObjective (ReaderT r m) where
   data Address e (ReaderT r m) = WrapReaderT (Address e m)
diff --git a/src/Control/Monad/Objective/IO.hs b/src/Control/Monad/Objective/IO.hs
--- a/src/Control/Monad/Objective/IO.hs
+++ b/src/Control/Monad/Objective/IO.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleInstances  #-}
+{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Objective.IO
@@ -13,7 +14,6 @@
 --
 -----------------------------------------------------------------------------
 module Control.Monad.Objective.IO  where
-import GHC.Base
 import Control.Monad.Objective.Class
 import Control.Concurrent
 import Control.Object
diff --git a/src/Control/Object.hs b/src/Control/Object.hs
--- a/src/Control/Object.hs
+++ b/src/Control/Object.hs
@@ -1,17 +1,42 @@
 {-# LANGUAGE Rank2Types, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}
 {-# LANGUAGE DeriveFunctor, DeriveDataTypeable #-}
 {-# LANGUAGE FunctionalDependencies, UndecidableInstances #-}
-module Control.Object where
+{-# LANGUAGE TypeOperators, TupleSections, GADTs #-}
+module Control.Object (
+  -- * Construction
+  Object(..),
+  liftO,
+  echo,
+  oneshot,
+  stateful,
+  variable,
+  -- * Composition
+  (.>>.),
+  transObject,
+  adaptObject,
+  sequential,
+  -- * Extensible objects
+  loner,
+  (.|>.),
+  sharing,
+  -- * Utilitites
+  Request(..),
+  request,
+  accept,
+  acceptM,
+  Lift(..),
+  get_,
+  modify_,
+  put_,
+  )
+where
 
-import Control.Comonad.Zero
-import Control.Comonad
-import Control.Monad.Trans.State
+import Control.Monad.Trans.State.Strict
 import Control.Monad
 import Data.Typeable
 import Control.Applicative
-import Data.Maybe
 import Control.Monad.Free
-import Control.Monad.Trans.Maybe
+import Data.OpenUnion1.Clean
 
 -- | The type 'Object e m' represents objects which can handle messages @e@, perform actions in the environment @m@.
 -- It can be thought of as an automaton that converts effects.
@@ -38,7 +63,9 @@
 (.>>.) :: 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.
+infixr 4 .>>.
+
+-- | Build an object using continuation passing style.
 oneshot :: (Functor e, Monad m) => (forall a. e (m a) -> m a) -> Object e m
 oneshot m = go where
   go = Object $ \e -> m (fmap return e) >>= \a -> return (a, go)
@@ -47,46 +74,66 @@
 -- | Build a stateful object.
 stateful :: Monad m => (forall a. e a -> StateT s m a) -> s -> Object e m
 stateful h = go where
-  go s = Object $ liftM (\(a, s) -> (a, go s)) . flip runStateT s . h
+  go s = Object $ liftM (\(a, s') -> (a, go s')) . flip runStateT s . h
+{-# INLINE stateful #-}
 
+-- | Convert a /method sequence/ into a sequential /method execution/.
+sequential :: Monad m => Object e m -> Object (Free e) m
+sequential obj = Object $ \x -> case x of
+  Pure a -> return (a, sequential obj)
+  Free f -> do
+    (a, obj') <- runObject obj f
+    runObject (sequential obj') a
+
+-- | A mutable variable.
+variable :: Applicative f => s -> Object (State s) f
+variable s = Object $ \m -> let (a, s') = runState m s in pure (a, variable s')
+
 -- | Build a stateful object, sharing out the state.
-sharing :: Monad m => (forall a. e a -> StateT s m a) -> s -> Object (AccessT s e) m
+sharing :: Monad m => (forall a. e a -> StateT s m a) -> s -> Object (State s |> e |> Nil) m
 sharing m = go where
-  go s = Object $ \k -> liftM (fmap go) $ case k of
-    LiftAccessT e -> runStateT (m e) s
-    Get cont -> return (cont s, s)
-    Put s' cont -> return (cont, s')
+  go s = Object $ \k -> liftM (fmap go) $ ($k)
+    $ (\n -> return $ runState n s)
+    ||> (\e -> runStateT (m e) s)
+    ||> exhaust
 {-# INLINE sharing #-}
 
--- | Like 'MonadState', but doesn't require 'Monad' as a prerequisite.
-class Stateful s f | f -> s where
-  get_ :: f s
-  put_ :: s -> f ()
+-- | An object that won't accept any messages.
+loner :: Functor m => Object Nil m
+loner = liftO exhaust
 
--- | Inflicts external state accessibility to arbitrary effects.
-data AccessT s f a = Get (s -> a) | Put s a | LiftAccessT (f a) deriving (Functor, Typeable)
+-- | Extend an object by adding another independent object.
+(.|>.) :: Functor m => Object f m -> Object (Union s) m -> Object (f |> Union s) m
+p .|>. q = Object $ fmap (fmap (.|>.q)) . runObject p ||> fmap (fmap (p .|>.)) . runObject q
 
-instance Stateful s (AccessT s f) where
-  get_ = Get id
-  put_ s = Put s ()
+data Request a b r = Request a (b -> r)
 
-instance (Functor f, Stateful s f) => Stateful s (Free f) where
-  get_ = liftF get_
-  put_ = liftF . put_
+class Lift f g | g -> f where
+  lift_ :: f a -> g a
 
--- | A mutable variable.
-variable :: Applicative f => s -> Object (Access s) f
-variable s = Object $ \x -> case x of
-  Get cont -> pure (cont s, variable s)
-  Put s' cont -> pure (cont, variable s')
-  LiftAccessT e -> pure (extract e, variable s)
+instance Lift (Request a b) (Request a b) where
+  lift_ = id
 
-type Access s = AccessT s Zero
+instance (f ∈ u) => Lift f (Union u) where
+  lift_ = liftU
 
--- | Convert a /method sequence/ into a sequential /method execution/.
-sequential :: Monad m => Object e m -> Object (Free e) m
-sequential obj = Object $ \x -> case x of
-  Pure a -> return (a, sequential obj)
-  Free f -> do
-    (a, obj') <- runObject obj f
-    runObject (sequential obj') a
+instance Lift (StateT s m) (StateT s m) where
+  lift_ = id
+
+get_ :: (Monad m, Lift (StateT s m) f) => f s
+get_ = lift_ get
+
+modify_ :: (Monad m, Lift (StateT s m) f) => (s -> s) -> f ()
+modify_ f = lift_ (modify f)
+
+put_ :: (Monad m, Lift (StateT s m) f) => s -> f ()
+put_ s = lift_ (put s)
+
+request :: (Lift (Request a b) f) => a -> f b
+request a = lift_ (Request a id)
+
+accept :: Functor f => (a -> f b) -> Request a b r -> f r
+accept f (Request a br) = fmap br (f a)
+
+acceptM :: Monad m => (a -> m b) -> Request a b r -> m r
+acceptM f (Request a br) = liftM br (f a)
