diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -15,3 +15,10 @@
 0.4.1
 - Documentation fixes
 - `Example` is renamed to `example` and is excluded from package's module hierarchy
+
+0.5.0
+- Refresh project to be compilable with latest GHC and libraries
+- Remove dependency on `mtl` package (`transformers` is sufficient)
+- Use `Except` instead of depricated `Error`
+- Remove support for `ListT` transformer since it is now depricated
+- Use standard `StateT` & `ReaderT` for `MonadCache` implementations
diff --git a/Control/Monad/Memo.hs b/Control/Monad/Memo.hs
--- a/Control/Monad/Memo.hs
+++ b/Control/Monad/Memo.hs
@@ -14,7 +14,7 @@
 
 module Control.Monad.Memo (
     module Control.Monad,
-    module Control.Monad.Trans,
+    module Control.Monad.Trans.Class,
     module Data.MapLike,
     module Data.MaybeLike,
     -- * MonadMemo class
@@ -107,7 +107,7 @@
 import Data.MaybeLike.Instances()
 
 import Control.Monad
-import Control.Monad.Trans
+import Control.Monad.Trans.Class
 
 
 {- $fibExample
diff --git a/Control/Monad/Memo/Array.hs b/Control/Monad/Memo/Array.hs
--- a/Control/Monad/Memo/Array.hs
+++ b/Control/Monad/Memo/Array.hs
@@ -53,7 +53,7 @@
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Fix
-import Control.Monad.Trans
+import Control.Monad.Trans.Class
 import Control.Monad.ST
 import System.IO
 
diff --git a/Control/Monad/Memo/Class.hs b/Control/Monad/Memo/Class.hs
--- a/Control/Monad/Memo/Class.hs
+++ b/Control/Monad/Memo/Class.hs
@@ -35,6 +35,7 @@
 
 ) where
 
+import Data.Tuple
 import Data.Function
 import Data.Maybe
 import Data.Either
@@ -43,9 +44,8 @@
 import Control.Monad.Trans.Class
 
 import Control.Monad.Trans.Cont
-import Control.Monad.Trans.Error
+import Control.Monad.Trans.Except
 import Control.Monad.Trans.Identity
-import Control.Monad.Trans.List
 import Control.Monad.Trans.Maybe
 import Control.Monad.Trans.Reader
 import qualified Control.Monad.Trans.State.Lazy as SL
@@ -81,7 +81,7 @@
 
 -- | Adapter for memoization of two-argument function
 for2 :: (((k1, k2) -> mv) -> (k1, k2) -> mv) -> (k1 -> k2 -> mv) -> k1 -> k2 -> mv
-for2 m f a b = m (\(a,b) -> f a b) (a,b)
+for2 m f = curry (m (uncurry f))
 
 -- | Adapter for memoization of three-argument function
 for3 :: (((k1, k2, k3) -> mv) -> (k1, k2, k3) -> mv) -> (k1 -> k2 -> k3 -> mv) -> k1 -> k2 -> k3 -> mv
@@ -161,11 +161,8 @@
 instance (MonadCache k (Maybe v) m) => MonadMemo k v (MaybeT m) where
     memo f = MaybeT . memol0 (runMaybeT . f)
 
-instance (MonadCache k [v] m) => MonadMemo k v (ListT m) where
-    memo f = ListT . memol0 (runListT . f)
-
-instance (Error e, MonadCache k  (Either e v) m) => MonadMemo k v (ErrorT e m) where
-    memo f = ErrorT . memol0 (runErrorT . f)
+instance (MonadCache k  (Either e v) m) => MonadMemo k v (ExceptT e m) where
+    memo f = ExceptT . memol0 (runExceptT . f)
 
 instance (MonadCache (r,k) v m) => MonadMemo k v (ReaderT r m) where
     memo f k = ReaderT $ \r -> memol0 (\(r, k) -> runReaderT (f k) r) (r, k)
diff --git a/Control/Monad/Memo/Vector.hs b/Control/Monad/Memo/Vector.hs
--- a/Control/Monad/Memo/Vector.hs
+++ b/Control/Monad/Memo/Vector.hs
@@ -52,7 +52,7 @@
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Fix
-import Control.Monad.Trans
+import Control.Monad.Trans.Class
 import Control.Monad.Primitive
 
 import Data.MaybeLike
diff --git a/Control/Monad/Memo/Vector/Expandable.hs b/Control/Monad/Memo/Vector/Expandable.hs
--- a/Control/Monad/Memo/Vector/Expandable.hs
+++ b/Control/Monad/Memo/Vector/Expandable.hs
@@ -50,7 +50,7 @@
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Fix
-import Control.Monad.Trans
+import Control.Monad.Trans.Class
 import Control.Monad.Primitive
 
 import Data.MaybeLike
diff --git a/Control/Monad/Memo/Vector/Unsafe.hs b/Control/Monad/Memo/Vector/Unsafe.hs
--- a/Control/Monad/Memo/Vector/Unsafe.hs
+++ b/Control/Monad/Memo/Vector/Unsafe.hs
@@ -50,7 +50,7 @@
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Fix
-import Control.Monad.Trans
+import Control.Monad.Trans.Class
 import Control.Monad.Primitive
 
 import Data.MaybeLike
diff --git a/Control/Monad/Trans/Memo/Map.hs b/Control/Monad/Trans/Memo/Map.hs
--- a/Control/Monad/Trans/Memo/Map.hs
+++ b/Control/Monad/Trans/Memo/Map.hs
@@ -31,7 +31,8 @@
 
 ) where
 
-import Control.Monad.Identity
+import Data.Functor.Identity
+import Control.Monad
 import Control.Monad.Trans.Memo.State
 
 import Data.MapLike.Instances()
diff --git a/Control/Monad/Trans/Memo/ReaderCache.hs b/Control/Monad/Trans/Memo/ReaderCache.hs
--- a/Control/Monad/Trans/Memo/ReaderCache.hs
+++ b/Control/Monad/Trans/Memo/ReaderCache.hs
@@ -7,16 +7,17 @@
 Stability   :  experimental
 Portability :  non-portable
 
-Generic StateCache - similar to `Control.Monad.Trans.Reader.ReaderT` but optimised for carrying cache container
+Generic StateCache - wrapper around `Control.Monad.Trans.Reader.ReaderT`
 
 -}
 
-{-# LANGUAGE NoImplicitPrelude, BangPatterns #-}
+{-# LANGUAGE NoImplicitPrelude, GeneralizedNewtypeDeriving #-}
 
 module Control.Monad.Trans.Memo.ReaderCache
 (
 
-  ReaderCache(..),
+  ReaderCache,
+  evalReaderCache,
   container
 
 ) where
@@ -24,62 +25,19 @@
 import Data.Function
 import Control.Applicative
 import Control.Monad
+import Control.Monad.IO.Class
 import Control.Monad.Fix
-import Control.Monad.Trans
+import Control.Monad.Trans.Class
+import Control.Monad.Trans.Reader
 
 
--- | Generic memoization cache which uses provided container
--- This is pretty much identical to `Control.Monad.Trans.Reader.ReaderT`,
--- but is tuned to speed up implementations which use unboxed mutable containers
-newtype ReaderCache c m a = ReaderCache { evalReaderCache :: c -> m a }
+newtype ReaderCache c m a = ReaderCache { toReaderT :: ReaderT c m a }
+    deriving (Functor, Applicative, Alternative, Monad, MonadPlus, MonadFix, MonadTrans, MonadIO)
 
+{-# INLINE evalReaderCache #-}
+evalReaderCache = runReaderT . toReaderT
+
 -- | Returns internal container
 container :: Monad m => ReaderCache c m c
 {-# INLINE container #-}
-container = ReaderCache $ \ !c -> return c
-
-
-instance (Functor m) => Functor (ReaderCache c m) where
-    {-# INLINE fmap #-}
-    fmap f m = ReaderCache $ \ !c -> fmap f (evalReaderCache m c)
-
-instance (Applicative m) => Applicative (ReaderCache arr m) where
-    {-# INLINE pure #-}
-    pure a  = ReaderCache $ \_ -> pure a
-    {-# INLINE (<*>) #-}
-    f <*> v = ReaderCache $ \ !c -> evalReaderCache f c <*> evalReaderCache v c
-
-instance (Alternative m) => Alternative (ReaderCache c m) where
-    {-# INLINE empty #-}
-    empty   = ReaderCache $ const empty
-    {-# INLINE (<|>) #-}
-    m <|> n = ReaderCache $ \ !c -> evalReaderCache m c <|> evalReaderCache n c
-
-instance (Monad m) => Monad (ReaderCache c m) where
-    {-# INLINE return #-}
-    return a = ReaderCache $ \ !c -> return a
-    {-# INLINE (>>=) #-}
-    m >>= k  = ReaderCache $ \ !c -> do
-        a <- evalReaderCache m c
-        evalReaderCache (k a) c
-    {-# INLINE (>>) #-}
-    m >> k   = ReaderCache $ \ !c -> do
-        evalReaderCache m c
-        evalReaderCache k c
-
-instance (MonadPlus m) => MonadPlus (ReaderCache c m) where
-    {-# INLINE mzero #-}
-    mzero       = lift mzero
-    {-# INLINE mplus #-}
-    m `mplus` n = ReaderCache $ \ !c -> evalReaderCache m c `mplus` evalReaderCache n c
-
-instance (MonadFix m) => MonadFix (ReaderCache c m) where
-    mfix f = ReaderCache $ \ !c -> mfix $ \a -> evalReaderCache (f a) c
-
-instance MonadTrans (ReaderCache c) where
-    {-# INLINE lift #-}
-    lift = ReaderCache . const
-
-instance (MonadIO m) => MonadIO (ReaderCache c m) where
-    {-# INLINE liftIO #-}
-    liftIO = lift . liftIO
+container = ReaderCache ask
diff --git a/Control/Monad/Trans/Memo/State.hs b/Control/Monad/Trans/Memo/State.hs
--- a/Control/Monad/Trans/Memo/State.hs
+++ b/Control/Monad/Trans/Memo/State.hs
@@ -33,10 +33,10 @@
 
 import Data.Tuple
 import Data.Function
+import Data.Functor.Identity
 import Control.Applicative
 import Control.Monad
-import Control.Monad.Trans
-import Control.Monad.Identity
+import Control.Monad.Trans.Class
 
 import qualified Data.MapLike as M
 import Control.Monad.Memo.Class
diff --git a/Control/Monad/Trans/Memo/StateCache.hs b/Control/Monad/Trans/Memo/StateCache.hs
--- a/Control/Monad/Trans/Memo/StateCache.hs
+++ b/Control/Monad/Trans/Memo/StateCache.hs
@@ -7,99 +7,47 @@
 Stability   :  experimental
 Portability :  non-portable (multi-param classes, flexible instances)
 
-Generic StateCache - similar to `Control.Monad.Trans.State.Strict.StateT` but optimised for carrying cache container
+Generic StateCache - wrapper around `Control.Monad.Trans.State.Strict.StateT`
 
 -}
 
-{-# LANGUAGE NoImplicitPrelude, BangPatterns #-}
+{-# LANGUAGE NoImplicitPrelude, GeneralizedNewtypeDeriving #-}
 
 module Control.Monad.Trans.Memo.StateCache
-(
- 
-    StateCache(..),
+( 
+    StateCache,
+    runStateCache,
     container,
     setContainer,
     evalStateCache
-
 ) where
 
 import Data.Function
 import Control.Applicative
 import Control.Monad
+import Control.Monad.IO.Class
 import Control.Monad.Fix
-import Control.Monad.Trans
+import Control.Monad.Trans.Class
+import Control.Monad.Trans.State.Strict
 
--- | Generic memoization cache which uses provided container which can also be updated by the computation.
--- This is pretty much identical to `Control.Monad.Trans.State.Strict.StateT`,
--- but is tuned to speed up implementations which use unboxed mutable containers
-newtype StateCache c m a = StateCache { runStateCache :: c -> m (a, c) }
 
+newtype StateCache c m a = StateCache { toStateT :: StateT c m a }
+    deriving (Functor, Applicative, Alternative, Monad, MonadPlus, MonadFix, MonadTrans, MonadIO)
+
+{-# INLINE runStateCache #-}
+runStateCache = runStateT . toStateT
+
 -- | Evaluates computation discarding the resulting container 
 evalStateCache :: Monad m => StateCache c m a -> c -> m a
 {-# INLINE evalStateCache #-}
-evalStateCache m !c = do
-    (a, _) <- runStateCache m c
-    return a
+evalStateCache = evalStateT . toStateT
 
 -- | Returns internal container
 container :: Monad m => StateCache c m c
 {-# INLINE container #-}
-container = StateCache $ \ !c -> return (c, c)
+container = StateCache get
 
 -- | Assigns new value to internal container
 setContainer :: Monad m => c -> StateCache c m ()
 {-# INLINE setContainer #-}
-setContainer c = StateCache $ \_ -> return ((), c)
-
-
-instance (Functor m) => Functor (StateCache c m) where
-    {-# INLINE fmap #-}
-    fmap f m = StateCache $ \ !c ->
-        fmap (\ (a, c') -> (f a, c')) (runStateCache m c)
-
-instance (Functor m, Monad m) => Applicative (StateCache c m) where
-    {-# INLINE pure #-}
-    pure = return
-    {-# INLINE (<*>) #-}
-    fa <*> aa = StateCache $ \ !c -> do
-        (f, c') <- runStateCache fa c
-        (a, c'') <- runStateCache aa c'
-        return (f a, c'')
-       
-instance (Functor m, MonadPlus m) => Alternative (StateCache c m) where
-    {-# INLINE empty #-}
-    empty = mzero
-    {-# INLINE (<|>) #-}
-    (<|>) = mplus
-
-instance (Monad m) => Monad (StateCache c m) where
-    {-# INLINE return #-}
-    return a = StateCache $ \ !c -> return (a, c)
-    {-# INLINE (>>=) #-}
-    m >>= k  = StateCache $ \ !c -> do
-        (a, !c') <- runStateCache m c
-        runStateCache (k a) c'
-    {-# INLINE (>>) #-}
-    m >> n   = StateCache $ \ !c -> do
-        (_, !c') <- runStateCache m c
-        runStateCache n c'         
-    fail str = StateCache $ \_ -> fail str
-
-instance (MonadPlus m) => MonadPlus (StateCache c m) where
-    {-# INLINE mzero #-}
-    mzero       = StateCache $ const mzero
-    {-# INLINE mplus #-}
-    m `mplus` n = StateCache $ \ !c -> runStateCache m c `mplus` runStateCache n c
-
-instance (MonadFix m) => MonadFix (StateCache c m) where
-    mfix f = StateCache $ \ !c -> mfix $ \ ~(a, _) -> runStateCache (f a) c
-
-instance MonadTrans (StateCache c) where
-    {-# INLINE lift #-}
-    lift m = StateCache $ \ !c -> do
-        a <- m
-        return (a, c)
-
-instance (MonadIO m) => MonadIO (StateCache c m) where
-    {-# INLINE liftIO #-}
-    liftIO = lift . liftIO
+setContainer = StateCache . put
diff --git a/benchmark/Main.hs b/benchmark/Main.hs
--- a/benchmark/Main.hs
+++ b/benchmark/Main.hs
@@ -12,7 +12,6 @@
 import Control.Monad.Memo.Vector.Unsafe
 import Control.Monad.Memo.Vector.Expandable
 import Criterion.Main
-import Criterion.Config
 
 
 -- Fibonacci numbers
@@ -181,7 +180,7 @@
 
 
 
-main = defaultMainWith defaultConfig (return ()) [
+main = defaultMainWith defaultConfig [
          bgroup "fib" [
            bgroup "pure" [
              bench "Map" $ whnf fibM n
@@ -198,14 +197,14 @@
            , bench "UVector exp" $ whnf fibSTUVE n
            ]
          , bgroup "IO" [
-             bench "Array" $ fibIOA n
-           , bench "UArray" $ fibIOUA n
-           , bench "Vector" $ fibIOV n
-           , bench "UVector" $ fibIOUV n
-           , bench "Vector unsafe" $ fibIOVU n
-           , bench "UVector unsafe" $ fibIOUVU n
-           , bench "Vector exp" $ fibIOVE n
-           , bench "UVector exp" $ fibIOUVE n
+             bench "Array" $ whnfIO (fibIOA n)
+           , bench "UArray" $ whnfIO (fibIOUA n)
+           , bench "Vector" $ whnfIO (fibIOV n)
+           , bench "UVector" $ whnfIO (fibIOUV n)
+           , bench "Vector unsafe" $ whnfIO (fibIOVU n)
+           , bench "UVector unsafe" $ whnfIO (fibIOUVU n)
+           , bench "Vector exp" $ whnfIO (fibIOVE n)
+           , bench "UVector exp" $ whnfIO (fibIOUVE n)
            ]
          ]
        , bgroup "knapsack" [
@@ -217,8 +216,8 @@
            , bench "UArray" $ whnf (knapSTUA ws vs) w
           ]
         , bgroup "IO" [
-             bench "Array" $ knapIOA ws vs w
-           , bench "UArray" $ knapIOUA ws vs w
+             bench "Array" $ whnfIO (knapIOA ws vs w)
+           , bench "UArray" $ whnfIO (knapIOUA ws vs w)
           ]
          ]
        , bgroup "LCS" [
@@ -236,12 +235,12 @@
        ]
     where
       -- fib arg
-      n = 50000
+      n = 100000
       -- knapsac args
-      ws = [1..100]
-      vs = [1..100]
-      w = 400
+      ws = [1..200]
+      vs = [1..200]
+      w = 800
       -- LCS args
-      as = [1..200]
-      bs = [100,102..400]
+      as = [1..400]
+      bs = [100,102..800]
            
diff --git a/monad-memo.cabal b/monad-memo.cabal
--- a/monad-memo.cabal
+++ b/monad-memo.cabal
@@ -1,6 +1,6 @@
 Name:               monad-memo
 
-Version:            0.4.1
+Version:            0.5.0
 
 -- A short (one-line) description of the package.
 Synopsis:           Memoization monad transformer
@@ -50,33 +50,36 @@
 
 
 -- Constraint on the version of Cabal needed to build this package.
-Cabal-version:      >=1.8
+Cabal-version:      >=1.10
 
-Tested-with:        GHC==7.0.4, GHC==7.4.2, GHC==7.6.2
+Tested-with:        GHC==7.10.3, GHC==8.2.2, GHC==8.4.3
 
 Extra-source-files:
-	  CHANGES
+  CHANGES,
+  README.md,
+  example/*.hs,
+  example/Customisation/*.hs
 
+
 source-repository head
   type:             git
-  location:	    https://github.com/EduardSergeev/monad-memo.git
+  location:	        https://github.com/EduardSergeev/monad-memo.git
 
 source-repository this
   type:             git
   location:         https://github.com/EduardSergeev/monad-memo.git
-  tag:              0.4.1
+  tag:              0.5.0
 
 
 Library
+  default-language: Haskell2010
   build-depends:
           base >= 3.0 && <= 5.0,
-          mtl >= 2.0,
           transformers >= 0.2,
           containers >= 0.3,
           array >= 0.3,
           vector >= 0.7,
           primitive >= 0.3
-  
   exposed-modules:
           Control.Monad.Memo,
           Control.Monad.Memo.Class,
@@ -96,12 +99,12 @@
           Data.MaybeLike.Instances
 
 Test-Suite tests
+  default-language: Haskell2010
   type:             exitcode-stdio-1.0
   hs-source-dirs:   . test
   main-is:          Main.hs
   build-depends: 
           base >= 3.0 && <= 5.0,
-          mtl >= 2.0,
           transformers >= 0.2,
           containers >= 0.3,
           array >= 0.3,
@@ -111,19 +114,52 @@
           QuickCheck >= 2.0,
           test-framework-quickcheck2 >= 0.2.9,
           test-framework >= 0.3.3
-
+  other-modules:
+          Control.Monad.Memo,
+          Control.Monad.Memo.Class,
+          Control.Monad.Trans.Memo.ReaderCache,
+          Control.Monad.Trans.Memo.StateCache,
+          Control.Monad.Trans.Memo.State,
+          Control.Monad.Trans.Memo.Map,
+          Control.Monad.Memo.Array,
+          Control.Monad.Memo.Array.Instances,
+          Control.Monad.Memo.Vector,
+          Control.Monad.Memo.Vector.Expandable,
+          Control.Monad.Memo.Vector.Unsafe,
+          Control.Monad.Memo.Vector.Instances,
+          Data.MapLike,
+          Data.MapLike.Instances,
+          Data.MaybeLike,
+          Data.MaybeLike.Instances
+          MemoTest          
 
 Benchmark all
+  default-language: Haskell2010
   type:             exitcode-stdio-1.0
   hs-source-dirs:   . benchmark
   main-is:          Main.hs
   build-depends:
           base >= 3.0 && <= 5.0,
-          mtl >= 2.0,
           transformers >= 0.2,
           containers >= 0.3,
           array >= 0.3,
           vector >= 0.7,
           primitive >= 0.3,
           criterion >= 0.6
-  ghc-options:      -O2
+  other-modules:
+          Control.Monad.Memo,
+          Control.Monad.Memo.Class,
+          Control.Monad.Trans.Memo.ReaderCache,
+          Control.Monad.Trans.Memo.StateCache,
+          Control.Monad.Trans.Memo.State,
+          Control.Monad.Trans.Memo.Map,
+          Control.Monad.Memo.Array,
+          Control.Monad.Memo.Array.Instances,
+          Control.Monad.Memo.Vector,
+          Control.Monad.Memo.Vector.Expandable,
+          Control.Monad.Memo.Vector.Unsafe,
+          Control.Monad.Memo.Vector.Instances,
+          Data.MapLike,
+          Data.MapLike.Instances,
+          Data.MaybeLike,
+          Data.MaybeLike.Instances 
diff --git a/test/MemoTest.hs b/test/MemoTest.hs
--- a/test/MemoTest.hs
+++ b/test/MemoTest.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleInstances, FlexibleContexts #-}
 
 module MemoTest
 (
@@ -6,11 +6,10 @@
 ) where
 
 import qualified Data.IntMap as IM
-import Control.Monad.Reader
-import Control.Monad.Writer
-import Control.Monad.State
-import Control.Monad.Cont
-import Control.Monad.List
+import Control.Monad.Trans.Reader
+import Control.Monad.Trans.Writer
+import Control.Monad.Trans.State
+import Control.Monad.Trans.Cont
 import Control.Monad.ST
 
 import Test.QuickCheck
@@ -170,31 +169,6 @@
     ((`runState`s) . fibs $ n) == (startEvalMemo . (`runStateT`s) . fibms $ n)
 
 
--- | With ListT
---
-data Tree a = Leaf !a | Fork (Tree a) (Tree a) deriving Eq
-
-partitions as = [ splitAt n as | n <- [1..length as - 1 ]]
-
-unfringe [a] = [Leaf a]
-unfringe as  = do
-  (l,k) <- partitions as
-  t <- unfringe l
-  u <- unfringe k
-  return (Fork t u)
-
-unfringem [a] = return (Leaf a)
-unfringem as = do
-  (l,k) <- ListT $ return (partitions as)
-  t <- memo unfringem l
-  u <- memo unfringem k
-  return (Fork t u)
-
-prop_ListEqv :: SmallList Char -> Bool
-prop_ListEqv (SmallList ls) =
-    unfringe ls == (startEvalMemo . runListT . unfringem $ ls)
-
-
 -- | Mutual recursion
 f :: Int -> (Int,String)
 f 0 = (1,"+")
@@ -416,7 +390,6 @@
                        testProperty "WriterEqv"         prop_WriterEqv,
                        testProperty "ContEqv"           prop_ContEqv,
                        testProperty "ContSTUEqv"        prop_ContSTUEqv,
-                       testProperty "ListEqv"           prop_ListEqv,
                        testProperty "StateEqv"          prop_StateEqv
                       ],
         testGroup "Others" [
