diff --git a/explicit-exception.cabal b/explicit-exception.cabal
--- a/explicit-exception.cabal
+++ b/explicit-exception.cabal
@@ -1,5 +1,5 @@
 Name:             explicit-exception
-Version:          0.1.3
+Version:          0.1.4
 License:          BSD3
 License-File:     LICENSE
 Author:           Henning Thielemann <haskell@henning-thielemann.de>
@@ -46,7 +46,7 @@
 Source-Repository this
   type:     darcs
   location: http://code.haskell.org/explicit-exception/
-  tag:      0.1.3
+  tag:      0.1.4
 
 Library
   Build-Depends: base >= 2, transformers >=0.0 && <0.2
diff --git a/src/Control/Monad/Exception/Asynchronous.hs b/src/Control/Monad/Exception/Asynchronous.hs
--- a/src/Control/Monad/Exception/Asynchronous.hs
+++ b/src/Control/Monad/Exception/Asynchronous.hs
@@ -5,7 +5,13 @@
 
 TODO:
 
-* Check whether laziness behaviour is reasonable.
+* Is it reasonable, that many functions match the exception lazily?
+  Or is lazy decoupling an operation that shall always be done explicitly?
+* Is the Null type appropriate anywhere?
+  Should it be better a Monoid type with mempty?
+  Shall Monoid.mempty be the default, or functions with explicit default values?
+* Shall we replace Monad constraint by Functor constraint,
+  where we only need liftM?
 -}
 module Control.Monad.Exception.Asynchronous (
    Exceptional(..),
@@ -17,8 +23,7 @@
    toSynchronous,
    throw,
    throwMonoid,
-   manySynchronousT,
-   processToSynchronousT_,
+   eatNothing,
    zipWith,
    append,
    continue,
@@ -36,13 +41,26 @@
    swapToSynchronousAsynchronous,
    swapToAsynchronousSynchronous,
 
+   ExceptionalT(..),
+   fromSynchronousT,
+   fromSynchronousMonoidT,
+   forceT,
+   mapExceptionT,
+   mapExceptionalT,
+   throwMonoidT,
+   eatNothingT,
+   bindT,
+   manySynchronousT,
+   manyMonoidT,
+   processToSynchronousT_,
+
    appendM,
    continueM,
    ) where
 
 import qualified Control.Monad.Exception.Synchronous as Sync
 
-import Control.Monad (mplus, liftM, )
+import Control.Monad (mplus, liftM, join, )
 import Control.Applicative (Applicative, liftA, )
 {-
 import Data.Traversable (Traversable, )
@@ -111,61 +129,26 @@
    maybe (Sync.Success a) Sync.Exception me
 
 
+{- |
+I think in most cases we want throwMonoid,
+thus we can replace 'throw' by 'throwMonoid'.
+-}
 throw :: e -> Exceptional e ()
 throw e = broken e ()
 
 throwMonoid :: Monoid a => e -> Exceptional e a
 throwMonoid e = broken e mempty
 
-
-
 {- |
-Repeat an action with synchronous exceptions until an exception occurs.
-Combine all atomic results using the @bind@ function.
-It may be @cons = (:)@ and @empty = []@ for @b@ being a list type.
-The @defer@ function may be @id@
-or @unsafeInterleaveIO@ for lazy read operations.
-The exception is returned as asynchronous exception.
--}
-manySynchronousT :: (Monad m) =>
-   (m (Exceptional e b) -> m (Exceptional e b))
-                           {- ^ @defer@ function -} ->
-   (a -> b -> b)           {- ^ @cons@ function -} ->
-   b                       {- ^ @empty@ -} ->
-   Sync.ExceptionalT e m a {- ^ atomic action to repeat -} ->
-   m (Exceptional e b)
-manySynchronousT defer cons empty action =
-   let recourse =
-          liftM force $ defer $
-          do r <- Sync.tryT action
-             case r of
-                Sync.Exception e -> return (Exceptional (Just e) empty)
-                Sync.Success x   -> liftM (fmap (cons x)) recourse
-   in  recourse
-
-{- |
-Scan @x@ using the @decons@ function
-and run an action with synchronous exceptions for each element fetched from @x@.
-Each invocation of an element action may stop this function
-due to an exception.
-If all element action can be performed successfully
-and if there is an asynchronous exception
-then at the end this exception is raised as synchronous exception.
-@decons@ function might be @viewL@.
+You might use an exception of type @Maybe e@ in 'manyMonoidT'
+in order to stop the loop.
+After finishing the loop you will want
+to turn the @Nothing@ exception into a success.
+This is achieved by this function.
 -}
-processToSynchronousT_ :: (Monad m) =>
-   (b -> Maybe (a,b))  {- ^ decons function -} ->
-   (a -> Sync.ExceptionalT e m ())
-                       {- ^ action that is run for each element fetched from @x@ -} ->
-   Exceptional e b     {- ^ value @x@ of type @b@ with asynchronous exception -} ->
-   Sync.ExceptionalT e m ()
-processToSynchronousT_ decons action (Exceptional me x) =
-   let recourse b0 =
-          maybe
-             (maybe (return ()) Sync.throwT me)
-             (\(a,b1) -> action a >> recourse b1)
-             (decons b0)
-   in  recourse x
+eatNothing :: Exceptional (Maybe e) a -> Exceptional e a
+eatNothing (Exceptional e a) =
+   Exceptional (join e) a
 
 
 -- ** handling of special result types
@@ -250,8 +233,6 @@
 
 {-
 fmap (f.g) = fmap f . fmap g
-
-
 -}
 instance Functor (Exceptional e) where
    fmap f ~(Exceptional e a) = Exceptional e (f a)
@@ -369,30 +350,41 @@
       Sync.Success s -> fmap Sync.Success s
 
 
-{-
--- * Monad transformer
+-- * Monad/Monoid transformer
 
+{- |
+In contrast to synchronous exceptions,
+the asynchronous monad transformer is not quite a monad.
+You must use the 'Monoid' interface or 'bindT' instead.
+-}
 newtype ExceptionalT e m a =
    ExceptionalT {runExceptionalT :: m (Exceptional e a)}
 
 
 fromSynchronousT :: Functor m =>
    a -> Sync.ExceptionalT e m a -> ExceptionalT e m a
-fromSynchronousT deflt (Sync.ExceptionalT mx) =
-   ExceptionalT $ fmap (fromSynchronous deflt) mx
-
-
-
-throwT :: (Monad m) =>
-   e -> ExceptionalT e m ()
-throwT = ExceptionalT . return . throw
+fromSynchronousT deflt =
+   ExceptionalT .
+   fmap (fromSynchronous deflt) .
+   Sync.runExceptionalT
 
+fromSynchronousMonoidT :: (Functor m, Monoid a) =>
+   Sync.ExceptionalT e m a -> ExceptionalT e m a
+fromSynchronousMonoidT =
+   fromSynchronousT mempty
 
 
 instance Functor m => Functor (ExceptionalT e m) where
    fmap f (ExceptionalT x) =
       ExceptionalT (fmap (fmap f) x)
 
+instance (Monad m, Monoid a) => Monoid (ExceptionalT e m a) where
+   mempty = ExceptionalT $ return mempty
+   mappend x y =
+      ExceptionalT $
+      appendM (runExceptionalT x) (runExceptionalT y)
+
+{-
 instance Applicative m => Applicative (ExceptionalT e m) where
    pure = ExceptionalT . pure . pure
    ExceptionalT f <*> ExceptionalT x =
@@ -407,6 +399,58 @@
          return $ Exceptional (ex ++ ey) y
 -}
 
+
+{- |
+see 'force'
+-}
+forceT :: Monad m => ExceptionalT e m a -> ExceptionalT e m a
+forceT =
+   ExceptionalT . liftM force . runExceptionalT
+
+mapExceptionT :: (Monad m) =>
+   (e0 -> e1) ->
+   ExceptionalT e0 m a ->
+   ExceptionalT e1 m a
+mapExceptionT f =
+   ExceptionalT . liftM (mapException f) . runExceptionalT
+
+mapExceptionalT ::
+   (m (Exceptional e0 a) -> n (Exceptional e1 b)) ->
+   ExceptionalT e0 m a -> ExceptionalT e1 n b
+mapExceptionalT f =
+   ExceptionalT . f . runExceptionalT
+
+
+throwMonoidT :: (Monad m, Monoid a) =>
+   e -> ExceptionalT e m a
+throwMonoidT = ExceptionalT . return . throwMonoid
+
+
+eatNothingT :: Monad m =>
+   ExceptionalT (Maybe e) m a -> ExceptionalT e m a
+eatNothingT =
+   mapExceptionalT (liftM eatNothing)
+
+
+infixl 1 `bindT`
+
+{- |
+The monadic bind operation.
+It cannot be made an instance of the Monad class method @(>>=)@
+since it requires a default return value
+in case the first action fails.
+We get this default value by the 'Monoid' method 'mempty'.
+-}
+bindT :: (Monad m, Monoid b) =>
+   ExceptionalT e m a ->
+   (a -> ExceptionalT e m b) ->
+   ExceptionalT e m b
+bindT x y =
+   ExceptionalT $
+   runExceptionalT x >>= \r ->
+   runExceptionalT $ maybe (y $ result r) throwMonoidT (exception r)
+
+
 infixr 1 {- `bindM`, -} `appendM`, `continueM`
 
 {-
@@ -435,3 +479,77 @@
    Maybe e -> m (Exceptional e a) -> m (Exceptional e a)
 continueMPlain x y =
    maybe y (return . throwMonoid) x
+
+
+{- |
+Repeat an action with synchronous exceptions until an exception occurs.
+Combine all atomic results using the @bind@ function.
+It may be @cons = (:)@ and @empty = []@ for @b@ being a list type.
+The @defer@ function may be @id@
+or @unsafeInterleaveIO@ for lazy read operations.
+The exception is returned as asynchronous exception.
+-}
+manySynchronousT :: (Monad m) =>
+   (m (Exceptional e b) -> m (Exceptional e b))
+                           {- ^ @defer@ function -} ->
+   (a -> b -> b)           {- ^ @cons@ function -} ->
+   b                       {- ^ @empty@ -} ->
+   Sync.ExceptionalT e m a {- ^ atomic action to repeat -} ->
+   m (Exceptional e b)
+manySynchronousT defer cons empty action =
+   let recourse =
+          liftM force $ defer $
+          do r <- Sync.tryT action
+             case r of
+                Sync.Exception e -> return (Exceptional (Just e) empty)
+                Sync.Success x   -> liftM (fmap (cons x)) recourse
+   in  recourse
+
+{-# DEPRECATED manySynchronousT "use manyMonoidT with appropriate Monad like LazyIO and result Monoid like Endo instead" #-}
+
+{- |
+We advise to use the Endo Monoid
+when you want to read a series of characters into a list.
+This means you use the difference lists technique
+in order to build the list, which is efficient.
+
+> import Data.Monoid (Endo, appEndo, )
+> import Control.Exception (try, )
+> import qualified Control.Monad.Exception.Synchronous as Sync
+
+> fmap (flip appEndo []) $ manyMonoidT (fromSynchronousMonoidT $ fmap (Endo . (:)) $ Sync.fromEitherT $ try getChar)
+
+If you want Lazy IO you must additionally convert @getChar@ to LazyIO monad.
+-}
+manyMonoidT :: (Monad m, Monoid a) =>
+   ExceptionalT e m a {- ^ atomic action to repeat -} ->
+   ExceptionalT e m a
+manyMonoidT act =
+   let -- like fmap, but doesn't require Functor instance of @m@
+       customFmap f = mapExceptionalT (liftM (fmap f))
+       go = act `bindT` \r -> customFmap (mappend r) go
+   in  go
+
+{- |
+Scan @x@ using the @decons@ function
+and run an action with synchronous exceptions for each element fetched from @x@.
+Each invocation of an element action may stop this function
+due to an exception.
+If all element actions can be performed successfully
+and if there is an asynchronous exception
+then at the end this exception is raised as synchronous exception.
+@decons@ function might be @Data.List.HT.viewL@.
+-}
+processToSynchronousT_ :: (Monad m) =>
+   (b -> Maybe (a,b))  {- ^ decons function -} ->
+   (a -> Sync.ExceptionalT e m ())
+                       {- ^ action that is run for each element fetched from @x@ -} ->
+   Exceptional e b     {- ^ value @x@ of type @b@ with asynchronous exception -} ->
+   Sync.ExceptionalT e m ()
+processToSynchronousT_ decons action (Exceptional me x) =
+   let recourse b0 =
+          maybe
+             (maybe (return ()) Sync.throwT me)
+             (\(a,b1) -> action a >> recourse b1)
+             (decons b0)
+   in  recourse x
diff --git a/src/Control/Monad/Exception/Synchronous.hs b/src/Control/Monad/Exception/Synchronous.hs
--- a/src/Control/Monad/Exception/Synchronous.hs
+++ b/src/Control/Monad/Exception/Synchronous.hs
@@ -1,6 +1,31 @@
 {- |
 Synchronous exceptions immediately abort a series of computations.
 We provide monads for describing this behaviour.
+In contrast to ErrorT from @mtl@ or @transformers@ package
+we do not pose restrictions on the exception type.
+
+How to tell, that a function can possibly throw more than one (kind of) exception?
+
+If you would use the exception type @(Either ParserException IOError)@
+then this is different from @(Either IOError ParserException)@.
+Thus we recommned using type classes for exceptions.
+Then you can use one type containing all exceptions in an application,
+but the type signature still tells which exceptions are actually possible.
+Examples:
+
+> parser :: ParserException e => ExceptionalT e ParserMonad a
+>
+> getLine :: IOException e => ExceptionalT e IO String
+>
+> fileParser :: (ParserException e, IOException e) => ExceptionalT e IO String
+
+Unfortunately, this way you cannot remove single exceptions
+from the constraints by catching them.
+You can only remove all of them using 'resolve' or none.
+For a more advanced approach,
+that allows removing exceptions constraints
+by some non-Haskell-98 type hackery,
+see the exception package by Joseph Iborra.
 -}
 module Control.Monad.Exception.Synchronous (
    Exceptional(..),
@@ -29,6 +54,7 @@
    resolveT,
    tryT,
    manyT,
+   manyMonoidT,
    ) where
 
 import Control.Applicative (Applicative(pure, (<*>)))
@@ -36,6 +62,7 @@
 import Control.Monad.Fix (MonadFix, mfix, )
 import Control.Monad.Trans (MonadTrans, lift, {- MonadIO(liftIO), -} )
 import Control.Monad.Trans.Error (ErrorT(ErrorT, runErrorT))
+import Data.Monoid(Monoid, mappend, mempty, Endo(Endo, appEndo), )
 
 import Prelude hiding (catch, )
 
@@ -281,13 +308,23 @@
    ExceptionalT e0 m a     {- ^ atomic action to repeat -} ->
    ExceptionalT e1 m b
 manyT handler cons empty action =
+   liftM (flip appEndo empty) $
+   manyMonoidT handler $
+   liftM (Endo . cons) action
+
+manyMonoidT :: (Monad m, Monoid a) =>
+   (e0 -> Maybe e1)        {- ^ exception handler -} ->
+   ExceptionalT e0 m a     {- ^ atomic action to repeat -} ->
+   ExceptionalT e1 m a
+manyMonoidT handler action =
    let recourse =
           do r <- lift $ tryT action
              case r of
-                Exception e -> maybe (return empty) throwT (handler e)
-                Success x   -> liftM (cons x) recourse
+                -- Exception e -> maybe (return empty) throwT (handler e)
+                -- more lazy
+                Exception e -> ExceptionalT $ return $ maybe (Success mempty) throw (handler e)
+                Success x   -> liftM (mappend x) recourse
    in  recourse
-
 
 
 
diff --git a/src/System/IO/Exception/TextFile.hs b/src/System/IO/Exception/TextFile.hs
--- a/src/System/IO/Exception/TextFile.hs
+++ b/src/System/IO/Exception/TextFile.hs
@@ -33,13 +33,14 @@
 getContentsSynchronous :: Handle -> EIO String
 getContentsSynchronous h =
    Sync.manyT
-      -- candidate for toMaybe
+      -- candidate for toMaybe from utility-ht
       (\e -> if isEOFError e then Nothing else Just e)
       (:) [] (getChar h)
 
 {- |
 This calls 'unsafeInterleaveIO'.
 Maybe we should also attach 'unsafe' to this function name?
+We should use the LazyIO type and manyT here.
 -}
 getContentsAsynchronous :: Handle -> SIO (Async.Exceptional IOException String)
 getContentsAsynchronous h =
