diff --git a/Control/Monad/Exception.hs b/Control/Monad/Exception.hs
--- a/Control/Monad/Exception.hs
+++ b/Control/Monad/Exception.hs
@@ -2,12 +2,15 @@
 {-# LANGUAGE UndecidableInstances #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverlappingInstances #-}
+
 module Control.Monad.Exception (
-    EM,  evalEM,  runEM,
-    EMT(..), evalEMT, runEMT,
+    EM,  runEM,
+    EMT(..), evalEMT, runEMT, runEMTParanoid,
     MonadZeroException(..),
     module Control.Monad.Exception.Class ) where
 
+import Control.Applicative
 import Control.Monad.Identity
 import Control.Monad.Exception.Class
 import Control.Monad.Fix
@@ -20,16 +23,22 @@
 
 type EM l = EMT l Identity
 
+
+{-
+data AnyException
+
+instance Exception e => Throws e AnyException
+
 -- | Run a computation which may fail
-evalEM :: EM (Caught SomeException l) a -> Either SomeException a
+evalEM :: EM AnyException a -> Either SomeException a
 evalEM (EMT a) = mapLeft wrapException (runIdentity a)
-
+-}
 mapLeft :: (a -> b) -> Either a r -> Either b r
 mapLeft f (Left x)  = Left (f x)
 mapLeft _ (Right x) = Right x
 
 -- | Run a safe computation
-runEM :: EM l a -> a
+runEM :: EM NoExceptions a -> a
 runEM = runIdentity . runEMT
 
 data MonadZeroException = MonadZeroException deriving (Show, Typeable)
@@ -40,11 +49,18 @@
 evalEMT :: Monad m => EMT (Caught SomeException l) m a -> m (Either SomeException a)
 evalEMT (EMT m) = mapLeft wrapException `liftM` m
 
-runEMT :: Monad m => EMT l m a -> m a
-runEMT (EMT m) = liftM f m where
+runEMT_gen :: Monad m => EMT l m a -> m a
+runEMT_gen (EMT m) = liftM f m where
   f (Right x) = x
-  f (Left  _) = error "evalEMT: The impossible happened"
+  f (Left  (WrapException (SomeException e))) = error (show e)
 
+runEMT :: Monad m => EMT NoExceptions m a -> m a
+runEMT = runEMT_gen
+
+-- | Check even runtime (@UncaughtException@) exceptions
+runEMTParanoid :: Monad m => EMT ParanoidMode m a -> m a
+runEMTParanoid = runEMT_gen
+
 instance Monad m => Functor (EMT l m) where
   fmap f emt = EMT $ do
                  v <- unEMT emt
@@ -60,10 +76,17 @@
                   Left e  -> return (Left e)
                   Right x -> unEMT (f x)
 
+instance Monad m => Applicative (EMT l m) where
+  pure  = return
+  (<*>) = ap
+
 instance (Exception e, Throws e l, Monad m) => MonadThrow e (EMT l m) where
   throw = EMT . return . Left . WrapException . toException
 instance (Exception e, Monad m) => MonadCatch e (EMT (Caught e l) m) (EMT l m) where
-  catch emt h = EMT $ do
+  catch = catchEMT
+
+catchEMT :: (Exception e, Monad m) => EMT (Caught e l) m a -> (e -> EMT l m a) -> EMT l m a
+catchEMT emt h = EMT $ do
                 v <- unEMT emt
                 case v of
                   Right x -> return (Right x)
diff --git a/Control/Monad/Exception/Class.hs b/Control/Monad/Exception/Class.hs
--- a/Control/Monad/Exception/Class.hs
+++ b/Control/Monad/Exception/Class.hs
@@ -4,11 +4,16 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE OverlappingInstances #-}
+
 module Control.Monad.Exception.Class (
        module Control.Monad,
        MonadThrow(..), MonadCatch(..),
        Throws, Caught,
-       WrapException(..), Exception(..), SomeException) where
+       WrapException(..), Exception(..), SomeException(..),
+       UncaughtException, NoExceptions, ParanoidMode
+       ) where
 
 import Control.Monad
 import Control.Monad.Trans
@@ -28,9 +33,15 @@
 import Data.Monoid
 import Prelude hiding (catch)
 
+
+-- Closing a type class with an unexported constraint
+--  @Private@  is unexported
+class Private l
+instance Private (Caught e l)
+
 {-| @Throws@ is the mechanism used to keep a type level
     list of exceptions.
-    .
+
     Usually there is no need for the user of this library
     to add further instances to @Throws@ except in one
     case: to encode subtyping. For instance if we have
@@ -40,8 +51,7 @@
  > instance Throws FileNotFoundException (Caught IOException l)
 
 -}
-
-class Exception e => Throws e s
+class (Private l, Exception e) => Throws e l --  | e -> l
 
 class Monad m => MonadThrow e m where
     throw :: e -> m a
@@ -55,20 +65,33 @@
 instance Exception e => MonadCatch e IO IO where
    catch   = Control.Exception.catch
 
+
 -- | A type level witness of a exception handler.
 data Caught e l
 
 instance Exception e => Throws e (Caught e l)
-instance Throws e l => Throws e (Caught e1 l)
+instance Throws e l  => Throws e (Caught e' l)
+
 -- | @SomeException@ is at the top of the exception hierarchy
 --   .
 --   Capturing SomeException captures every possible exception
 instance Exception e => Throws e (Caught SomeException l)
 
+data NoExceptions
+instance Private NoExceptions
+
+data ParanoidMode
+instance Private ParanoidMode
+
+-- | Uncaught Exceptions model runtime exceptions which are not checked.
+--
+--   In order to declare a runtime exception it must be made an instance of @UncaughtException@
+class Exception e => UncaughtException e
+instance UncaughtException e => Throws e NoExceptions
+
 -- Labelled SomeException
 -- ------------------------
 newtype WrapException l = WrapException {wrapException::SomeException} deriving Show
-
 
 -- Throw and Catch instances for the Either and ErrorT monads
 -- -----------------------------------------------------------
diff --git a/control-monad-exception.cabal b/control-monad-exception.cabal
--- a/control-monad-exception.cabal
+++ b/control-monad-exception.cabal
@@ -1,5 +1,5 @@
 name: control-monad-exception
-version: 0.2
+version: 0.3
 Cabal-Version:  >= 1.2.3
 build-type: Simple
 license: PublicDomain
@@ -7,8 +7,8 @@
 maintainer: pepeiborra@gmail.com
 homepage: http://github.com/pepeiborra/control-monad-exception
 description: 
-  This package provides explicitly typed exceptions as a library.
-  .
+  This package provides explicitly typed, checked exceptions as a library.
+
   /Example/
   .
   > data Expr = Add Expr Expr | Div Expr Expr | Val Double
@@ -34,6 +34,7 @@
   > eval :: (Throws DivideByZero l, Throws SumOverflow l) => Expr -> EM l Double
   > eval `catch` \ (e::DivideByZero) -> return (-1)  :: Throws SumOverflow l => Expr -> EM l Double
   > runEM(eval `catch` \ (e::SomeException) -> return (-1))  :: Expr -> Double
+
 synopsis: Explicitly typed exceptions
 category: Control, Monads
 stability: experimental
@@ -53,14 +54,13 @@
       base >= 3.0 && <4
   else
     build-depends:
-      base >= 4.0
+      base >= 4 && < 5
 
   build-depends:
     transformers >= 0.0.1 && <0.2,
     monads-fd >= 0.0 && <0.1
   extensions:  MultiParamTypeClasses, 
                FunctionalDependencies,
-               OverlappingInstances, 
                FlexibleInstances,
                EmptyDataDecls,
                DeriveDataTypeable,
