diff --git a/Control/Monad/Parallel.hs b/Control/Monad/Parallel.hs
--- a/Control/Monad/Parallel.hs
+++ b/Control/Monad/Parallel.hs
@@ -62,12 +62,19 @@
 import Prelude ()
 import Control.Concurrent (forkIO)
 import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)
-import Control.Monad (Monad, (>>=), return)
+import Control.Monad (Monad, (>>=), return, liftM)
+import Control.Monad.Trans.Identity (IdentityT(IdentityT, runIdentityT))
+import Control.Monad.Trans.Maybe (MaybeT(MaybeT, runMaybeT))
+import Control.Monad.Trans.Error (ErrorT(ErrorT, runErrorT), Error)
+import Control.Monad.Trans.List (ListT(ListT, runListT))
+import Control.Monad.Trans.Reader (ReaderT(ReaderT, runReaderT))
 import Control.Parallel (par, pseq)
+import Data.Either (Either(..))
+import Data.Function (($), (.), const)
 import Data.Functor.Identity (Identity)
 import Data.Int (Int)
-import Data.List (foldr, map, replicate)
-import Data.Maybe (Maybe)
+import Data.List ((++), foldr, map, replicate)
+import Data.Maybe (Maybe(Just, Nothing))
 import System.IO (IO)
 
 -- | Class of monads that can perform two computations in parallel and bind their results together.
@@ -130,6 +137,11 @@
 instance MonadParallel Maybe
 instance MonadParallel []
 
+instance MonadParallel ((->) r) where
+   bindM2 f ma mb r = let a = ma r
+                          b = mb r
+                      in a `par` (b `pseq` f a b r)
+
 -- | IO is parallelizable by `forkIO`.
 instance MonadParallel IO where
    bindM2 f ma mb = do vb <- newEmptyMVar
@@ -138,11 +150,54 @@
                        b <- takeMVar vb
                        f a b
 
+instance MonadParallel m => MonadParallel (IdentityT m) where
+   bindM2 f ma mb = IdentityT (bindM2 f' (runIdentityT ma) (runIdentityT mb))
+     where f' a b = runIdentityT (f a b)
+
+instance MonadParallel m => MonadParallel (MaybeT m) where
+   bindM2 f ma mb = MaybeT (bindM2 f' (runMaybeT ma) (runMaybeT mb))
+     where f' (Just a) (Just b) = runMaybeT (f a b)
+           f' _ _ = return Nothing
+
+instance (MonadParallel m, Error e) => MonadParallel (ErrorT e m) where
+   bindM2 f ma mb = ErrorT (bindM2 f' (runErrorT ma) (runErrorT mb))
+     where f' (Right a) (Right b) = runErrorT (f a b)
+           f' (Left e) _ = return (Left e)
+           f' _ (Left e) = return (Left e)
+
+instance MonadParallel m => MonadParallel (ListT m) where
+   bindM2 f ma mb = ListT (bindM2 f' (runListT ma) (runListT mb))
+     where f' as bs = foldr concat (return []) [runListT (f a b) | a <- as, b <- bs]
+           concat m m' = do {x <- m; y <- m'; return (x ++ y)}
+
+instance MonadParallel m => MonadParallel (ReaderT r m) where
+   bindM2 f ma mb = ReaderT (\r-> bindM2 (f' r) (runReaderT ma r) (runReaderT mb r))
+     where f' r a b = runReaderT (f a b) r
+
 instance MonadFork Maybe
 instance MonadFork []
 
+instance MonadFork ((->) r) where
+   forkExec e = \r-> let result = e r
+                     in result `par` (return result)
+
 -- | IO is forkable by `forkIO`.
 instance MonadFork IO where
    forkExec ma = do v <- newEmptyMVar
                     _ <- forkIO (ma >>= putMVar v)
                     return (takeMVar v)
+
+instance MonadFork m => MonadFork (IdentityT m) where
+   forkExec ma = IdentityT (liftM IdentityT $ forkExec (runIdentityT ma))
+
+instance MonadFork m => MonadFork (MaybeT m) where
+   forkExec ma = MaybeT (liftM (Just . MaybeT) $ forkExec (runMaybeT ma))
+
+instance (MonadFork m, Error e) => MonadFork (ErrorT e m) where
+   forkExec ma = ErrorT (liftM (Right . ErrorT) $ forkExec (runErrorT ma))
+
+instance MonadFork m => MonadFork (ListT m) where
+   forkExec ma = ListT (liftM ((:[]) . ListT) $ forkExec (runListT ma))
+
+instance MonadFork m => MonadFork (ReaderT r m) where
+   forkExec ma = ReaderT (\r-> liftM (ReaderT . const) $ forkExec (runReaderT ma r))
diff --git a/Test/TestParallel.hs b/Test/TestParallel.hs
new file mode 100644
--- /dev/null
+++ b/Test/TestParallel.hs
@@ -0,0 +1,110 @@
+{- 
+    Copyright 2010 Mario Blazevic
+
+    This file is part of the Streaming Component Combinators (SCC) project.
+
+    The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
+    License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
+    version.
+
+    SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along with SCC.  If not, see
+    <http://www.gnu.org/licenses/>.
+-}
+
+-- | The "Control.Monad.Parallel" tests.
+
+module Main where
+
+import Prelude hiding (mapM)
+import Control.Monad (liftM)
+import Control.Monad.Trans.Identity (IdentityT(..))
+import Control.Monad.Trans.Maybe (MaybeT(..))
+import Control.Monad.Trans.Error (ErrorT(..))
+import Control.Monad.Trans.List (ListT(..))
+import Control.Monad.Trans.Reader (ReaderT(..))
+import Control.Parallel (pseq)
+import Data.Functor.Identity (runIdentity)
+import Data.Maybe (fromJust)
+import System.Environment (getArgs)
+
+import Control.Monad.Parallel
+
+parFib :: MonadParallel m => Int -> Int -> m Integer
+parFib _ 0 = return 1
+parFib _ 1 = return 1
+parFib 1 n = applyM fib n
+parFib k n = bindM2 (\a b-> return (a + b)) (parFib (mod k 2) (n - 1)) (parFib (mod (k + 1) 2) (n - 2))
+
+forkFib :: MonadFork m => Int -> Int -> m Integer
+forkFib _ 0 = return 1
+forkFib _ 1 = return 1
+forkFib 1 n = applyM fib n
+forkFib k n = do mf1 <- forkExec (forkFib (mod k 2) (n - 1))
+                 f2 <- forkFib (mod (k + 1) 2) (n - 2)
+                 f1 <- mf1
+                 return (f1 + f2)
+
+parSeqFib :: MonadParallel m => Int -> Int -> m Integer
+parSeqFib t n = liftM sum $ mapM (applyM fib) (split t n)
+   where split 1 n = [n]
+         split k n | k > 1 = let (max : rest) = split (k - 1) n
+                             in rest ++ [max - 1, max - 2]
+
+applyM f n = let result = f n in result `pseq` return result
+
+fib 0 = 1
+fib 1 = 1
+fib n = fib (n - 2) + fib (n - 1)
+
+main = do args <- getArgs
+          if length args /= 5
+             then putStr help
+             else do let [taskName, method, monad, size, threads] = args
+                         task :: MonadFork m => Int -> Int -> m Integer
+                         task = case (method, taskName) of ("par", "fib") -> parFib
+                                                           ("fork", "fib") -> forkFib
+                                                           ("[par]", "fib") -> parSeqFib
+                                                           _ -> error (help ++ "Bad method or task.")
+                         parOnlyTask :: MonadParallel m => Int -> Int -> m Integer
+                         parOnlyTask = case (method, taskName) of ("par", "fib") -> parFib
+                                                                  ("[par]", "fib") -> parSeqFib
+                                                                  _ -> error ("Monad " ++ monad ++ " can't do "
+                                                                              ++ method)
+                     result <- case monad of "Identity" -> return $ runIdentity $ parOnlyTask (read threads) (read size)
+                                             "IdentityT-[]" -> return $ head $ runIdentityT 
+                                                               $ task (read threads) (read size)
+                                             "IdentityT-IO" -> runIdentityT $ task (read threads) (read size)
+                                             "Maybe" -> return $ fromJust $ task (read threads) (read size)
+                                             "MaybeT-[]" -> return $ fromJust $ head $ runMaybeT
+                                                            $ task (read threads) (read size)
+                                             "MaybeT-IO" -> liftM fromJust $ runMaybeT 
+                                                            $ task (read threads) (read size)
+                                             "ErrorT-[]" -> return $ (either error id) $ head $ runErrorT
+                                                            $ task (read threads) (read size)
+                                             "ErrorT-IO" -> liftM (either error id) $ runErrorT 
+                                                            $ task (read threads) (read size)
+                                             "->" -> return $ ($ 0) $ task (read threads) (read size)
+                                             "[]" -> return $ head $ task (read threads) (read size)
+                                             "ListT-Maybe" -> return $ head $ fromJust $ runListT 
+                                                              $ task (read threads) (read size)
+                                             "ListT-IO" -> liftM head $ runListT 
+                                                           $ task (read threads) (read size)
+                                             "ReaderT-[]" -> return $ head 
+                                                             $ runReaderT (task (read threads) (read size)) ()
+                                             "ReaderT-IO" -> runReaderT (task (read threads) (read size)) ()
+                                             "IO" -> task (read threads) (read size)
+                                             _ -> error (help ++ "Bad monad.")
+                     print result
+
+help = "Usage: test-parallel <task> <method> <monad> <threads> <size>\n"
+       ++ "  where <task>    is 'fib',\n"
+       ++ "        <method>  is 'par', 'fork', or '[par]'\n"
+       ++ "        <monad>   is 'Identity', 'Maybe', '->', '[]', "
+       ++ "                     'IdentityT-IO', 'IdentityT-[]', 'MaybeT-IO', 'MaybeT-[]'," 
+       ++ "                     'ErrorT-IO', 'ErrorT-[]', 'ListT-IO', 'ListT-Maybe',"
+       ++ "                     'ReaderT-IO', 'ReaderT-[]', or 'IO',\n"
+       ++ "        <threads> is the number of threads to launch,\n"
+       ++ "    and <size>    is the size of the task.\n"
diff --git a/TestParallel.hs b/TestParallel.hs
deleted file mode 100644
--- a/TestParallel.hs
+++ /dev/null
@@ -1,83 +0,0 @@
-{- 
-    Copyright 2010 Mario Blazevic
-
-    This file is part of the Streaming Component Combinators (SCC) project.
-
-    The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
-    License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
-    version.
-
-    SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along with SCC.  If not, see
-    <http://www.gnu.org/licenses/>.
--}
-
--- | The "Control.Monad.Parallel" tests.
-
-module Main where
-
-import Prelude hiding (mapM)
-import Control.Monad (liftM)
-import Control.Parallel (pseq)
-import Data.Functor.Identity (runIdentity)
-import Data.Maybe (fromJust)
-import System.Environment (getArgs)
-
-import Control.Monad.Parallel
-
-parFib :: MonadParallel m => Int -> Int -> m Integer
-parFib _ 0 = return 1
-parFib _ 1 = return 1
-parFib 1 n = applyM fib n
-parFib k n = bindM2 (\a b-> return (a + b)) (parFib (mod k 2) (n - 1)) (parFib (mod (k + 1) 2) (n - 2))
-
-forkFib :: MonadFork m => Int -> Int -> m Integer
-forkFib _ 0 = return 1
-forkFib _ 1 = return 1
-forkFib 1 n = applyM fib n
-forkFib k n = do mf1 <- forkExec (forkFib (mod k 2) (n - 1))
-                 f2 <- forkFib (mod (k + 1) 2) (n - 2)
-                 f1 <- mf1
-                 return (f1 + f2)
-
-parSeqFib :: MonadParallel m => Int -> Int -> m Integer
-parSeqFib t n = liftM sum $ mapM (applyM fib) (split t n)
-   where split 1 n = [n]
-         split k n | k > 1 = let (max : rest) = split (k - 1) n
-                             in rest ++ [max - 1, max - 2]
-
-applyM f n = let result = f n in result `pseq` return result
-
-fib 0 = 1
-fib 1 = 1
-fib n = fib (n - 2) + fib (n - 1)
-
-main = do args <- getArgs
-          if length args /= 5
-             then putStr help
-             else do let [taskName, method, monad, size, threads] = args
-                         task :: MonadFork m => Int -> Int -> m Integer
-                         task = case (method, taskName) of ("par", "fib") -> parFib
-                                                           ("fork", "fib") -> forkFib
-                                                           ("[par]", "fib") -> parSeqFib
-                                                           _ -> error (help ++ "Bad method or task.")
-                         parOnlyTask :: MonadParallel m => Int -> Int -> m Integer
-                         parOnlyTask = case (method, taskName) of ("par", "fib") -> parFib
-                                                                  ("[par]", "fib") -> parSeqFib
-                                                                  _ -> error ("Monad " ++ monad ++ " can't do "
-                                                                              ++ method)
-                     result <- case monad of "Maybe" -> return $ fromJust $ task (read threads) (read size)
-                                             "[]" -> return $ head $ task (read threads) (read size)
-                                             "Identity" -> return $ runIdentity $ parOnlyTask (read threads) (read size)
-                                             "IO" -> task (read threads) (read size)
-                                             _ -> error (help ++ "Bad monad.")
-                     print result
-
-help = "Usage: test-parallel <task> <method> <monad> <threads> <size>\n"
-       ++ "  where <task>    is 'fib',\n"
-       ++ "        <method>  is 'par', 'fork', or '[par]'\n"
-       ++ "        <monad>   is 'Identity', 'Maybe', '[]', or 'IO',\n"
-       ++ "        <threads> is the number of threads to launch,\n"
-       ++ "    and <size>    is the size of the task.\n"
diff --git a/monad-parallel.cabal b/monad-parallel.cabal
--- a/monad-parallel.cabal
+++ b/monad-parallel.cabal
@@ -1,5 +1,5 @@
 Name:                monad-parallel
-Version:             0.5.2
+Version:             0.7
 Cabal-Version:       >= 1.2
 Build-Type:          Simple
 Synopsis:            Parallel execution of monadic computations
@@ -16,7 +16,7 @@
 Author:              Mario Blazevic
 Maintainer:          blamario@yahoo.com
 Homepage:            http://trac.haskell.org/SCC/wiki/monad-parallel
-Extra-source-files:  TestParallel.hs
+Extra-source-files:  Test/TestParallel.hs
 -- Source-repository head
 --   type:              darcs
 --   location:          http://code.haskell.org/SCC/
