diff --git a/Foundation/Internal/CallStack.hs b/Foundation/Internal/CallStack.hs
--- a/Foundation/Internal/CallStack.hs
+++ b/Foundation/Internal/CallStack.hs
@@ -9,7 +9,7 @@
 
 import GHC.Stack (HasCallStack)
 
-#elif MIN_VERSION_base(4,8,0)
+#elif MIN_VERSION_base(4,8,1)
 
 import qualified GHC.Stack
 
diff --git a/Foundation/Monad.hs b/Foundation/Monad.hs
new file mode 100644
--- /dev/null
+++ b/Foundation/Monad.hs
@@ -0,0 +1,11 @@
+module Foundation.Monad
+    ( MonadIO(..)
+    , MonadFailure(..)
+    , MonadThrow(..)
+    , MonadCatch(..)
+    , MonadTrans(..)
+    ) where
+
+import Foundation.Monad.MonadIO
+import Foundation.Monad.Exception
+import Foundation.Monad.Transformer
diff --git a/Foundation/Monad/Base.hs b/Foundation/Monad/Base.hs
new file mode 100644
--- /dev/null
+++ b/Foundation/Monad/Base.hs
@@ -0,0 +1,17 @@
+module Foundation.Monad.Base
+    ( Functor(..)
+    , Applicative(..)
+    , Monad(..)
+    , MonadIO(..)
+    , MonadFailure(..)
+    , MonadThrow(..)
+    , MonadCatch(..)
+    , MonadTrans(..)
+    , IdentityT
+    ) where
+
+import Foundation.Internal.Base (Functor(..), Applicative(..), Monad(..))
+import Foundation.Monad.MonadIO
+import Foundation.Monad.Exception
+import Foundation.Monad.Transformer
+import Foundation.Monad.Identity
diff --git a/Foundation/Monad/Exception.hs b/Foundation/Monad/Exception.hs
new file mode 100644
--- /dev/null
+++ b/Foundation/Monad/Exception.hs
@@ -0,0 +1,42 @@
+
+module Foundation.Monad.Exception
+    ( MonadFailure(..)
+    , MonadThrow(..)
+    , MonadCatch(..)
+    ) where
+
+import           Foundation.Internal.Base
+import qualified Control.Exception (throwIO, catch)
+
+-- | Monad that can represent failure
+--
+-- Similar to MonadFail but with a parametrized Failure linked to the Monad
+class Monad m => MonadFailure m where
+    -- | The associated type with the MonadFailure, representing what
+    -- failure can be encoded in this monad
+    type Failure m
+
+    -- | Raise a Failure through a monad.
+    mFail :: Failure m -> m ()
+
+-- | Monad that can throw exception
+class Monad m => MonadThrow m where
+    -- | Throw immediatity an exception.
+    -- Only a 'MonadCatch' monad will be able to catch the exception using 'catch'
+    throw :: Exception e => e -> m a
+
+-- | Monad that can catch exception
+class MonadThrow m => MonadCatch m where
+    catch :: Exception e => m a -> (e -> m a) -> m a
+
+instance MonadFailure Maybe where
+    type Failure Maybe = ()
+    mFail _ = Nothing
+instance MonadFailure (Either a) where
+    type Failure (Either a) = a
+    mFail a = Left a
+
+instance MonadThrow IO where
+    throw = Control.Exception.throwIO
+instance MonadCatch IO where
+    catch = Control.Exception.catch
diff --git a/Foundation/Monad/Identity.hs b/Foundation/Monad/Identity.hs
new file mode 100644
--- /dev/null
+++ b/Foundation/Monad/Identity.hs
@@ -0,0 +1,44 @@
+module Foundation.Monad.Identity
+    ( IdentityT
+    ) where
+
+import Foundation.Internal.Base hiding (throw)
+import Foundation.Monad.MonadIO
+import Foundation.Monad.Exception
+import Foundation.Monad.Transformer
+
+newtype IdentityT m a = IdentityT { runIdentityT :: m a }
+
+instance Functor m => Functor (IdentityT m) where
+    fmap f (IdentityT m) = IdentityT (f `fmap` m)
+    {-# INLINE fmap #-}
+
+instance Applicative m => Applicative (IdentityT m) where
+    pure x = IdentityT (pure x)
+    {-# INLINE pure #-}
+    fab <*> fa = IdentityT (runIdentityT fab <*> runIdentityT fa)
+    {-# INLINE (<*>) #-}
+
+instance Monad m => Monad (IdentityT m) where
+    return x = IdentityT (return x)
+    {-# INLINE return #-}
+    ma >>= mb = IdentityT $ runIdentityT ma >>= runIdentityT . mb
+    {-# INLINE (>>=) #-}
+
+instance MonadTrans IdentityT where
+    lift = IdentityT
+    {-# INLINE lift #-}
+
+instance MonadIO m => MonadIO (IdentityT m) where
+    liftIO f = lift (liftIO f)
+    {-# INLINE liftIO #-}
+
+instance MonadFailure m => MonadFailure (IdentityT m) where
+    type Failure (IdentityT m) = Failure m
+    mFail = IdentityT . mFail
+
+instance MonadThrow m => MonadThrow (IdentityT m) where
+    throw e = IdentityT (throw e)
+
+instance MonadCatch m => MonadCatch (IdentityT m) where
+    catch (IdentityT m) c = IdentityT $ m `catch` (runIdentityT . c)
diff --git a/Foundation/Monad/MonadIO.hs b/Foundation/Monad/MonadIO.hs
new file mode 100644
--- /dev/null
+++ b/Foundation/Monad/MonadIO.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE CPP #-}
+module Foundation.Monad.MonadIO
+    ( MonadIO(..)
+    ) where
+
+#if MIN_VERSION_base(4,9,0)
+import Control.Monad.IO.Class
+#else
+import Foundation.Internal.Base
+
+-- | Monads in which 'IO' computations may be embedded.
+class Monad m => MonadIO m where
+    -- | Lift a computation from the 'IO' monad.
+    liftIO :: IO a -> m a
+
+instance MonadIO IO where
+    liftIO io = io
+
+#endif
diff --git a/Foundation/Monad/Reader.hs b/Foundation/Monad/Reader.hs
new file mode 100644
--- /dev/null
+++ b/Foundation/Monad/Reader.hs
@@ -0,0 +1,43 @@
+module Foundation.Monad.Reader
+    ( ReaderT
+    ) where
+
+import Foundation.Internal.Base (($), (.), const)
+import Foundation.Monad.Base
+
+-- | Reader Transformer
+newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
+
+instance Functor m => Functor (ReaderT r m) where
+    fmap f m = ReaderT $ fmap f . runReaderT m
+    {-# INLINE fmap #-}
+
+instance Applicative m => Applicative (ReaderT r m) where
+    pure a     = ReaderT $ const (pure a)
+    {-# INLINE pure #-}
+    fab <*> fa = ReaderT $ \r -> runReaderT fab r <*> runReaderT fa r
+    {-# INLINE (<*>) #-}
+
+instance Monad m => Monad (ReaderT r m) where
+    return a = ReaderT $ const (return a)
+    {-# INLINE return #-}
+    ma >>= mab = ReaderT $ \r -> runReaderT ma r >>= \a -> runReaderT (mab a) r
+    {-# INLINE (>>=) #-}
+
+instance MonadTrans (ReaderT r) where
+    lift f = ReaderT $ \_ -> f
+    {-# INLINE lift #-}
+
+instance MonadIO m => MonadIO (ReaderT r m) where
+    liftIO f = lift (liftIO f)
+    {-# INLINE liftIO #-}
+
+instance MonadFailure m => MonadFailure (ReaderT r m) where
+    type Failure (ReaderT r m) = Failure m
+    mFail e = ReaderT $ \_ -> mFail e
+
+instance MonadThrow m => MonadThrow (ReaderT r m) where
+    throw e = ReaderT $ \_ -> throw e 
+
+instance MonadCatch m => MonadCatch (ReaderT r m) where
+    catch (ReaderT m) c = ReaderT $ \r -> m r `catch` (\e -> runReaderT (c e) r)
diff --git a/Foundation/Monad/State.hs b/Foundation/Monad/State.hs
new file mode 100644
--- /dev/null
+++ b/Foundation/Monad/State.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE TupleSections #-}
+module Foundation.Monad.State
+    ( StateT
+    ) where
+
+import Foundation.Internal.Base (($), (.))
+import Foundation.Monad.Base
+
+-- | State Transformer
+newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }
+
+instance Functor m => Functor (StateT s m) where
+    fmap f m = StateT $ \s1 -> (\(a, s2) -> (f a, s2)) `fmap` runStateT m s1
+    {-# INLINE fmap #-}
+
+instance (Applicative m, Monad m) => Applicative (StateT s m) where
+    pure a     = StateT $ \s -> (,s) `fmap` pure a
+    {-# INLINE pure #-}
+    fab <*> fa = StateT $ \s1 -> do
+        (ab,s2) <- runStateT fab s1
+        (a, s3) <- runStateT fa s2
+        return (ab a, s3)
+    {-# INLINE (<*>) #-}
+
+instance (Functor m, Monad m) => Monad (StateT s m) where
+    return a = StateT $ \s -> (,s) `fmap` return a
+    {-# INLINE return #-}
+    ma >>= mab = StateT $ \s1 -> runStateT ma s1 >>= \(a, s2) -> runStateT (mab a) s2
+    {-# INLINE (>>=) #-}
+
+instance MonadTrans (StateT s) where
+    lift f = StateT $ \s -> f >>= return . (,s)
+    {-# INLINE lift #-}
+
+instance (Functor m, MonadIO m) => MonadIO (StateT s m) where
+    liftIO f = lift (liftIO f)
+    {-# INLINE liftIO #-}
+
+instance (Functor m, MonadFailure m) => MonadFailure (StateT s m) where
+    type Failure (StateT s m) = Failure m
+    mFail e = StateT $ \s -> ((,s) `fmap` mFail e)
+
+instance (Functor m, MonadThrow m) => MonadThrow (StateT s m) where
+    throw e = StateT $ \_ -> throw e 
+
+instance (Functor m, MonadCatch m) => MonadCatch (StateT s m) where
+    catch (StateT m) c = StateT $ \s1 -> m s1 `catch` (\e -> runStateT (c e) s1)
diff --git a/Foundation/Monad/Transformer.hs b/Foundation/Monad/Transformer.hs
new file mode 100644
--- /dev/null
+++ b/Foundation/Monad/Transformer.hs
@@ -0,0 +1,10 @@
+module Foundation.Monad.Transformer
+    ( MonadTrans(..)
+    ) where
+
+import Foundation.Internal.Base
+
+-- | Basic Transformer class
+class MonadTrans trans where
+    -- | Lift a computation from an inner monad to the current transformer monad
+    lift :: Monad m => m a -> trans m a
diff --git a/Foundation/Primitive/Types.hs b/Foundation/Primitive/Types.hs
--- a/Foundation/Primitive/Types.hs
+++ b/Foundation/Primitive/Types.hs
@@ -360,15 +360,15 @@
 instance PrimType CChar where
     primSizeInBytes _ = Size 1
     {-# INLINE primSizeInBytes #-}
-    primBaUIndex ba (Offset n) = CChar (primBaUIndex ba (Offset n :: Offset Int8))
+    primBaUIndex ba (Offset n) = CChar (primBaUIndex ba (Offset n))
     {-# INLINE primBaUIndex #-}
-    primMbaURead mba (Offset n) = CChar <$> primMbaURead mba (Offset n :: Offset Int8)
+    primMbaURead mba (Offset n) = CChar <$> primMbaURead mba (Offset n)
     {-# INLINE primMbaURead #-}
     primMbaUWrite mba (Offset n) (CChar int8) = primMbaUWrite mba (Offset n) int8
     {-# INLINE primMbaUWrite #-}
-    primAddrIndex addr (Offset n) = CChar $ primAddrIndex addr (Offset n :: Offset Int8)
+    primAddrIndex addr (Offset n) = CChar $ primAddrIndex addr (Offset n)
     {-# INLINE primAddrIndex #-}
-    primAddrRead addr (Offset n) = CChar <$> primAddrRead addr (Offset n :: Offset Int8)
+    primAddrRead addr (Offset n) = CChar <$> primAddrRead addr (Offset n)
     {-# INLINE primAddrRead #-}
     primAddrWrite addr (Offset n) (CChar int8) = primAddrWrite addr (Offset n) int8
     {-# INLINE primAddrWrite #-}
diff --git a/Foundation/String/ASCII.hs b/Foundation/String/ASCII.hs
--- a/Foundation/String/ASCII.hs
+++ b/Foundation/String/ASCII.hs
@@ -42,7 +42,7 @@
 import           Foundation.Primitive.Monad
 import           Foundation.Foreign
 
-import GHC.Int
+import GHC.Word
 import GHC.Types
 import GHC.Prim
 
@@ -51,31 +51,31 @@
 import qualified Prelude
 import Foundation.Class.Bifunctor
 
-ccharToChar :: CChar -> Char
-ccharToChar (CChar (I8# i)) = C# (chr# i)
-charToCChar :: Char -> CChar
-charToCChar (C# i) = CChar (I8# (ord# i))
+cucharToChar :: CUChar -> Char
+cucharToChar (CUChar (W8# i)) = C# (chr# (word2Int# i))
+charToCUChar :: Char -> CUChar
+charToCUChar (C# i) = CUChar (W8# (int2Word# (ord# i)))
 
 -- | Opaque packed array of characters in the ASCII encoding
-newtype AsciiString = AsciiString { toBytes :: UArray CChar }
+newtype AsciiString = AsciiString { toBytes :: UArray CUChar }
     deriving (Typeable, Monoid, Eq, Ord)
 
-newtype MutableAsciiString st = MutableAsciiString (MVec.MUArray CChar st)
+newtype MutableAsciiString st = MutableAsciiString (MVec.MUArray CUChar st)
     deriving (Typeable)
 
 instance Show AsciiString where
-    show = fmap ccharToChar . toList
+    show = fmap cucharToChar . toList
 instance IsString AsciiString where
-    fromString = fromList . fmap charToCChar
+    fromString = fromList . fmap charToCUChar
 instance IsList AsciiString where
-    type Item AsciiString = CChar
+    type Item AsciiString = CUChar
     fromList = sFromList
     toList = sToList
 
-type instance C.Element AsciiString = CChar
+type instance C.Element AsciiString = CUChar
 
 instance C.InnerFunctor AsciiString where
-    imap = ccharMap
+    imap = cucharMap
 instance C.Collection AsciiString where
     null = null
     length = length
@@ -109,7 +109,7 @@
   -- TODO Use a string builder once available
   zipWith f a b = sFromList (C.zipWith f a b)
 
-next :: AsciiString -> Offset CChar -> (# CChar, Offset CChar #)
+next :: AsciiString -> Offset CUChar -> (# CUChar, Offset CUChar #)
 next (AsciiString ba) (Offset n) = (# h, Offset (n + 1) #)
   where
     !h = Vec.unsafeIndex ba n
@@ -121,10 +121,10 @@
 ------------------------------------------------------------------------
 -- real functions
 
-sToList :: AsciiString -> [CChar]
+sToList :: AsciiString -> [CUChar]
 sToList s = loop azero
   where
-    nbBytes :: Size CChar
+    nbBytes :: Size CUChar
     !nbBytes = size s
     !end = azero `offsetPlusE` nbBytes
     loop idx
@@ -132,7 +132,7 @@
         | otherwise  =
             let (# c , idx' #) = next s idx in c : loop idx'
 
-sFromList :: [CChar] -> AsciiString
+sFromList :: [CUChar] -> AsciiString
 sFromList = AsciiString . fromList
 {-# INLINE [0] sFromList #-}
 
@@ -179,34 +179,34 @@
 -- > splitOn (== ':') "abc::def"   == ["abc","","def"]
 -- > splitOn (== ':') "::abc::def" == ["","","abc","","def"]
 --
-splitOn :: (CChar -> Bool) -> AsciiString -> [AsciiString]
+splitOn :: (CUChar -> Bool) -> AsciiString -> [AsciiString]
 splitOn predicate = fmap AsciiString . Vec.splitOn predicate . toBytes
 
-break :: (CChar -> Bool) -> AsciiString -> (AsciiString, AsciiString)
+break :: (CUChar -> Bool) -> AsciiString -> (AsciiString, AsciiString)
 break predicate = bimap AsciiString AsciiString . Vec.break predicate . toBytes
 {-# INLINE[0] break #-}
 
 {-# RULES "break (== 'c')" [3] forall c . break (== c) = breakElem c #-}
 
-breakElem :: CChar -> AsciiString -> (AsciiString, AsciiString)
+breakElem :: CUChar -> AsciiString -> (AsciiString, AsciiString)
 breakElem !el (AsciiString ba) =
     let (# v1,v2 #) = Vec.splitElem el ba in (AsciiString v1, AsciiString v2)
 {-# INLINE breakElem #-}
 
-intersperse :: CChar -> AsciiString -> AsciiString
+intersperse :: CUChar -> AsciiString -> AsciiString
 intersperse sep = AsciiString . Vec.intersperse sep . toBytes
 
-span :: (CChar -> Bool) -> AsciiString -> (AsciiString, AsciiString)
+span :: (CUChar -> Bool) -> AsciiString -> (AsciiString, AsciiString)
 span predicate = break (not . predicate)
 
 -- | size in bytes
-size :: AsciiString -> Size CChar
+size :: AsciiString -> Size CUChar
 size = Size . C.length . toBytes
 
 length :: AsciiString -> Int
 length s = let (Size l) = size s in l
 
-replicate :: Int -> CChar -> AsciiString
+replicate :: Int -> CUChar -> AsciiString
 replicate n c = AsciiString $ Vec.create n (const c)
 
 -- | Copy the AsciiString
@@ -215,7 +215,7 @@
 
 -- | Allocate a MutableAsciiString of a specific size in bytes.
 new :: PrimMonad prim
-    => Size CChar -- ^ in number of bytes, not of elements.
+    => Size CUChar -- ^ in number of bytes, not of elements.
     -> prim (MutableAsciiString (PrimState prim))
 new n = MutableAsciiString `fmap` MVec.new n
 
@@ -227,28 +227,28 @@
         then freeze ms
         else C.take filled `fmap` freeze ms
 
-ccharMap :: (CChar -> CChar) -> AsciiString -> AsciiString
-ccharMap f = AsciiString . Vec.map f . toBytes
+cucharMap :: (CUChar -> CUChar) -> AsciiString -> AsciiString
+cucharMap f = AsciiString . Vec.map f . toBytes
 
-snoc :: AsciiString -> CChar -> AsciiString
+snoc :: AsciiString -> CUChar -> AsciiString
 snoc (AsciiString ba) = AsciiString . Vec.snoc ba
 
-cons :: CChar -> AsciiString -> AsciiString
+cons :: CUChar -> AsciiString -> AsciiString
 cons c = AsciiString . Vec.cons c . toBytes
 
-unsnoc :: AsciiString -> Maybe (AsciiString, CChar)
+unsnoc :: AsciiString -> Maybe (AsciiString, CUChar)
 unsnoc str = first AsciiString <$> Vec.unsnoc (toBytes str)
 
-uncons :: AsciiString -> Maybe (CChar, AsciiString)
+uncons :: AsciiString -> Maybe (CUChar, AsciiString)
 uncons str = second AsciiString <$> Vec.uncons (toBytes str)
 
-find :: (CChar -> Bool) -> AsciiString -> Maybe CChar
+find :: (CUChar -> Bool) -> AsciiString -> Maybe CUChar
 find predicate = Vec.find predicate . toBytes
 
-sortBy :: (CChar -> CChar -> Ordering) -> AsciiString -> AsciiString
+sortBy :: (CUChar -> CUChar -> Ordering) -> AsciiString -> AsciiString
 sortBy sortF = AsciiString . Vec.sortBy sortF . toBytes
 
-filter :: (CChar -> Bool) -> AsciiString -> AsciiString
+filter :: (CUChar -> Bool) -> AsciiString -> AsciiString
 filter p s = fromList $ Data.List.filter p $ toList s
 
 reverse :: AsciiString -> AsciiString
@@ -259,7 +259,7 @@
 -- If the input contains invalid sequences, it will trigger runtime async errors when processing data.
 --
 -- In doubt, use 'fromBytes'
-fromBytesUnsafe :: UArray CChar -> AsciiString
+fromBytesUnsafe :: UArray CUChar -> AsciiString
 fromBytesUnsafe = AsciiString
 
 lines :: AsciiString -> [AsciiString]
diff --git a/foundation.cabal b/foundation.cabal
--- a/foundation.cabal
+++ b/foundation.cabal
@@ -1,5 +1,5 @@
 Name:                foundation
-Version:             0.0.2
+Version:             0.0.3
 Synopsis:            Alternative prelude with batteries and no dependencies
 Description:
     A custom prelude with no dependencies apart from base.
@@ -30,7 +30,7 @@
 Homepage:            https://github.com/haskell-foundation/foundation
 Bug-Reports:         https://github.com/haskell-foundation/foundation/issues
 Cabal-Version:       >=1.10
-tested-with:         GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1
+tested-with:         GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1
 extra-source-files:  README.md
                      cbits/*.h
 
@@ -70,6 +70,9 @@
                      Foundation.Foreign
                      Foundation.Collection
                      Foundation.Primitive
+                     Foundation.Monad
+                     Foundation.Monad.Reader
+                     Foundation.Monad.State
                      Foundation.System.Info
                      Foundation.Strict
                      Foundation.Parser
@@ -124,6 +127,11 @@
                      Foundation.Primitive.Monad
                      Foundation.Primitive.Utils
                      Foundation.Primitive.FinalPtr
+                     Foundation.Monad.MonadIO
+                     Foundation.Monad.Exception
+                     Foundation.Monad.Transformer
+                     Foundation.Monad.Identity
+                     Foundation.Monad.Base
                      Foundation.Array.Chunked.Unboxed
                      Foundation.Array.Common
                      Foundation.Array.Unboxed
diff --git a/tests/Test/Data/ASCII.hs b/tests/Test/Data/ASCII.hs
--- a/tests/Test/Data/ASCII.hs
+++ b/tests/Test/Data/ASCII.hs
@@ -13,5 +13,5 @@
 import Test.Tasty.QuickCheck
 
 -- | a better generator for unicode Character
-genAsciiChar :: Gen CChar
+genAsciiChar :: Gen CUChar
 genAsciiChar = toEnum <$> choose (1, 127)
