diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -6,3 +6,4 @@
 # Haskell-transaction
 
 Monadic representation of transactions.
+Alike `List`, but can be declared with `do` notations.
diff --git a/src/Data/Transaction.hs b/src/Data/Transaction.hs
--- a/src/Data/Transaction.hs
+++ b/src/Data/Transaction.hs
@@ -1,4 +1,10 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TypeFamilies #-}
 
 {- |
 Module      :  Data.Transaction
@@ -14,26 +20,67 @@
 module Data.Transaction
   (
   -- * Constructors
-  action
-
+    action
   -- * Converters
   , reduce
   , toList
   , tMap
   , tFilter
   , tFilterMap
-
   -- * Types
   , Transaction
   , TransactionM
   ) where
 
+import Prelude hiding
+  ( all
+  , any
+  , drop
+  , dropWhile
+  , filter
+  , foldMap
+  , foldl
+  , foldl1
+  , foldr
+  , foldr1
+  , head
+  , init
+  , last
+  , length
+  , null
+  , repeat
+  , replicate
+  , span
+  , tail
+  , take
+  , takeWhile
+  )
+
+import Data.Bifunctor (Bifunctor(..))
+import qualified Data.Monoid as Monoid
+import Data.MonoTraversable
+  ( Element
+  , GrowingAppend
+  , MonoFoldable(..)
+  , MonoFunctor(..)
+  , MonoPointed(..)
+  , MonoTraversable(..)
+  )
+import Data.Semigroup as Sem
+import Data.Sequences
+  ( Index
+  , IsSequence(..)
+  , SemiSequence(..)
+  , defaultSnoc
+  , defaultSortBy
+  )
+
 {- ==============
  -     Types
  - ============== -}
-
 data TransactionM a x
-  = TVal a (TransactionM a x)
+  = TVal a
+         (TransactionM a x)
   | TNull x
   deriving (Functor)
 
@@ -49,10 +96,206 @@
   TVal a next >>= f = TVal a (next >>= f)
   TNull a >>= f = f a
 
+instance Sem.Semigroup (Transaction a) where
+  TVal a next <> t = TVal a (next <> t)
+  TNull _ <> t = t
+
+instance Monoid (Transaction a) where
+  mempty = TNull ()
+#if !(MIN_VERSION_base(4,11,0))
+  mappend = (<>)
+#endif
+
+instance Bifunctor TransactionM where
+  first :: forall a b x. (a -> b) -> TransactionM a x -> TransactionM b x
+  first _ (TNull a) = pure a
+  first f (TVal a next) = TVal (f a) $ first f next
+  second :: forall a x y. (x -> y) -> TransactionM a x -> TransactionM a y
+  second = fmap
+
+type instance Element (Transaction a) = a
+
+instance MonoFunctor (Transaction a) where
+  omap :: (a -> a) -> Transaction a -> Transaction a
+  omap = first
+
+instance MonoFoldable (Transaction a) where
+  otoList = toList
+  ocompareLength :: Integral i => Transaction a -> i -> Ordering
+  ocompareLength (TNull ()) i = 0 `compare` i
+  ocompareLength (TVal _ next) i
+    | i <= 0 = GT
+    | otherwise = ocompareLength next (i - 1)
+  ofoldMap = foldMap
+  ofoldr = foldr
+  ofoldl' = foldl'
+  ofoldr1Ex = foldr1
+  ofoldl1Ex' = foldl1'
+
+foldMap :: (Monoid m) => (a -> m) -> Transaction a -> m
+foldMap f = foldr (\x m -> f x Monoid.<> m) mempty
+
+foldr :: (a -> b -> b) -> b -> Transaction a -> b
+foldr _ b (TNull ()) = b
+foldr f b (TVal a next) = f a (foldr f b next)
+
+foldl :: (b -> a -> b) -> b -> Transaction a -> b
+foldl f b (TVal a next) = foldl f (f b a) next
+foldl _ b (TNull ()) = b
+
+foldl' :: (b -> a -> b) -> b -> Transaction a -> b
+foldl' (??) z xs = (foldr (?!) id xs) z
+  where
+    x ?! g = g . (?? x)
+
+foldr1 :: (a -> a -> a) -> Transaction a -> a
+foldr1 _ (TNull ()) = error "Transaction.foldr1: empty transaction"
+foldr1 _ (TVal a (TNull ())) = a
+foldr1 f (TVal a next) = f a (foldr1 f next)
+
+foldl1' :: (a -> a -> a) -> Transaction a -> a
+foldl1' _ (TNull ()) = error "Transaction.foldl1': empty transaction"
+foldl1' f (TVal a next) = foldl' f a next
+
+#if MIN_VERSION_base(4,11,0)
+{-# NOINLINE [1] length #-}
+length :: Transaction a -> Int
+length t = lenAcc t 0
+
+lenAcc :: Transaction a -> Int -> Int
+lenAcc (TNull ()) n = n
+lenAcc (TVal _ next) n = lenAcc next (n + 1)
+#endif
+
+instance MonoPointed (Transaction a) where
+  opoint :: a -> Transaction a
+  opoint = action
+
+instance SemiSequence (Transaction a) where
+  type Index (Transaction a) = Int
+  intersperse :: a -> Transaction a -> Transaction a
+  intersperse _ (TNull ()) = pure ()
+  intersperse sep (TVal a next) = TVal a $ prependToAll sep next
+  reverse :: Transaction a -> Transaction a
+  reverse = reduce (\t a -> TVal a t) (TNull ())
+  find :: (a -> Bool) -> Transaction a -> Maybe a
+  find p t =
+    case tFilter p t of
+      TNull () -> Nothing
+      TVal a _ -> Just a
+  sortBy :: (a -> a -> Ordering) -> Transaction a -> Transaction a
+  sortBy = defaultSortBy
+  cons :: a -> Transaction a -> Transaction a
+  cons a t = TVal a t
+  snoc :: Transaction a -> a -> Transaction a
+  snoc = defaultSnoc
+
+prependToAll :: a -> Transaction a -> Transaction a
+prependToAll _ (TNull ()) = pure ()
+prependToAll sep (TVal a next) = TVal sep $ TVal a $ prependToAll sep next
+
+instance GrowingAppend (Transaction a)
+
+instance MonoTraversable (Transaction a) where
+  otraverse :: Applicative f => (a -> f a) -> Transaction a -> f (Transaction a)
+  otraverse _ (TNull ()) = pure $ pure ()
+  otraverse f (TVal a next) = TVal <$> f a <*> otraverse f next
+
+instance IsSequence (Transaction a) where
+  fromList :: [a] -> Transaction a
+  fromList [] = pure ()
+  fromList (x:xs) = TVal x $ fromList xs
+
+#if MIN_VERSION_mono_traversable(1,0,2)
+  lengthIndex :: Transaction a -> Int
+  lengthIndex = length
+#endif
+
+  {-# NOINLINE [1] filter #-}
+  filter :: (a -> Bool) -> Transaction a -> Transaction a
+  filter _ (TNull ()) = pure ()
+  filter p (TVal a next)
+    | p a = TVal a $ filter p next
+    | otherwise = filter p next
+  filterM :: Monad m => (a -> m Bool) -> Transaction a -> m (Transaction a)
+  filterM _ (TNull ()) = pure $ pure ()
+  filterM mp (TVal a next) = do
+    b <- mp a
+    next' <- filterM mp next
+    pure $
+      if b
+        then TVal a next'
+        else next'
+  break :: (a -> Bool) -> Transaction a -> (Transaction a, Transaction a)
+  break p = span (not . p)
+  span :: (a -> Bool) -> Transaction a -> (Transaction a, Transaction a)
+  span _ t@(TNull ()) = (t, t)
+  span p t@(TVal a next)
+    | p a =
+      let (y, z) = span p next
+       in (TVal a y, z)
+    | otherwise = (pure (), t)
+  dropWhile :: (a -> Bool) -> Transaction a -> Transaction a
+  dropWhile _ (TNull ()) = pure ()
+  dropWhile p t@(TVal a next)
+    | p a = dropWhile p next
+    | otherwise = t
+  takeWhile :: (a -> Bool) -> Transaction a -> Transaction a
+  takeWhile _ (TNull ()) = pure ()
+  takeWhile p (TVal a next)
+    | p a = TVal a $ takeWhile p next
+    | otherwise = pure ()
+  splitAt :: Int -> Transaction a -> (Transaction a, Transaction a)
+  splitAt n t = (take n t, drop n t)
+  take :: Int -> Transaction a -> Transaction a
+  take n _
+    | n <= 0 = pure ()
+  take _ (TNull ()) = pure ()
+  take n (TVal a next) = TVal a $ take (n - 1) next
+  drop :: Int -> Transaction a -> Transaction a
+  drop n t
+    | n <= 0 = t
+  drop _ (TNull ()) = pure ()
+  drop n (TVal _ next) = drop (n - 1) next
+  uncons :: Transaction a -> Maybe (a, Transaction a)
+  uncons (TNull ()) = Nothing
+  uncons (TVal a next) = Just (a, next)
+  unsnoc (TNull ()) = Nothing
+  unsnoc (TVal a0 next0) = Just (loop id a0 next0)
+    where
+      loop front a (TNull ()) = (front $ pure (), a)
+      loop front a (TVal y z) = loop (front . (TVal a)) y z
+  {-# INLINE partition #-}
+  partition :: (a -> Bool) -> Transaction a -> (Transaction a, Transaction a)
+  partition p t = foldr (select p) (pure (), pure ()) t
+  {-# INLINE replicate #-}
+  replicate :: Int -> a -> Transaction a
+  replicate n a = take n (repeat a)
+  replicateM :: Monad m => Int -> m a -> m (Transaction a)
+  replicateM cnt0 f = loop cnt0
+    where
+      loop cnt
+        | cnt <= 0 = pure $ pure ()
+        | otherwise = TVal <$> f <*> loop (cnt - 1)
+
+{-# INLINE [0] repeat #-}
+repeat :: a -> Transaction a
+repeat a = t
+  where
+    t = TVal a t
+
+select ::
+     (a -> Bool)
+  -> a
+  -> (Transaction a, Transaction a)
+  -> (Transaction a, Transaction a)
+select p x ~(ts, fs)
+  | p x = (TVal x ts, fs)
+  | otherwise = (ts, TVal x fs)
+
 {- ==============
  -   Operators
  - ============== -}
-
 {- |
 >>> :{
 toList $ do
@@ -61,6 +304,14 @@
   action 6
 :}
 [4,5,6]
+
+>>> :{
+toList $ filter even $ do
+  action 4
+  action 5
+  action 6
+:}
+[4,6]
 -}
 action :: a -> Transaction a
 action a = TVal a $ pure ()
@@ -68,8 +319,7 @@
 {- ==============
  -   Converters
  - ============== -}
-
-{- |
+{- | An alias of 'first' for convenience.
 >>> :{
 toList $ do
   action 4
@@ -83,7 +333,11 @@
 tMap :: (a -> b) -> Transaction a -> Transaction b
 tMap f = tFilterMap (pure . f)
 
-{- |
+{-# DEPRECATED
+tFilter "Use `IsSequence.filter` instead."
+ #-}
+
+{- | An alias of 'filter'.
 >>> :{
 toList $ do
   action 4
@@ -95,11 +349,12 @@
 [4,6,7]
 -}
 tFilter :: (a -> Bool) -> Transaction a -> Transaction a
-tFilter p = tFilterMap $ \a ->
-  if p a
-    then Just a
-    else Nothing
+tFilter = filter
 
+{-# DEPRECATED
+tFilterMap "This will be removed in a future release."
+ #-}
+
 {- |
 >>> :{
 toList $ do
@@ -114,15 +369,14 @@
 tFilterMap :: (a -> Maybe b) -> Transaction a -> Transaction b
 tFilterMap f (TVal a next) =
   case f a of
-    Just b ->
-      TVal b $ tFilterMap f next
-    Nothing ->
-      tFilterMap f next
+    Just b -> TVal b $ tFilterMap f next
+    Nothing -> tFilterMap f next
 tFilterMap _ (TNull ()) = TNull ()
 
+{- | An alias of `foldl` for convenience.
+-}
 reduce :: (b -> a -> b) -> b -> Transaction a -> b
-reduce f b (TVal a next) = reduce f (f b a) next
-reduce _ b (TNull ()) = b
+reduce = foldl
 
 toList :: Transaction a -> [a]
-toList trans = reduce (\f a -> f . (a:)) id trans []
+toList trans = reduce (\f a -> f . (a :)) id trans []
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,2 +1,415 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module Main where
+
+import Prelude hiding
+  ( all
+  , any
+  , break
+  , drop
+  , dropWhile
+  , filter
+  , foldMap
+  , foldl
+  , foldl1
+  , foldr
+  , foldr1
+  , head
+  , init
+  , last
+  , length
+  , repeat
+  , null
+  , replicate
+  , reverse
+  , seq
+  , span
+  , splitAt
+  , tail
+  , take
+  , takeWhile
+  )
+import Data.Bifunctor (Bifunctor(..))
+import Data.MonoTraversable
+  ( MonoFoldable(..)
+  , MonoFunctor(..)
+  , MonoPointed(..)
+  , MonoTraversable(..)
+  )
+import Data.Sequences (IsSequence(..), SemiSequence(..))
+import Data.Transaction
+import Test.Hspec
+import Test.Hspec.QuickCheck
+import Test.QuickCheck
+import Test.QuickCheck.Exception
+
 main :: IO ()
-main = putStrLn "Test suite not yet implemented"
+main = hspec spec
+
+exceptionableEq :: Eq a => Either AnException a -> Either AnException a -> Bool
+exceptionableEq (Left _) (Left _) = True
+exceptionableEq (Right a) (Right b) = a == b
+exceptionableEq _ _ = False
+
+spec :: Spec
+spec = do
+  describe "MonoFunctor" $ do
+    describe "omap" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (a :: [Int]) ->
+          omap f a == (toList . omap f . listToTrans) a
+
+  describe "MonoFoldable" $ do
+    describe "ofoldMap" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (a :: [Int]) ->
+          (ofoldMap f a :: String) ==
+          (ofoldMap f $ listToTrans a)
+    describe "ofoldr" $ do
+      prop "is equivalent to list" $
+        \f (a :: String) (mono :: [Int]) ->
+          (ofoldr (applyFun2 f) a mono) ==
+          (ofoldr (applyFun2 f) a $ listToTrans mono)
+    describe "ofoldl'" $ do
+      prop "is equivalent to list" $
+        \f (a :: String) (mono :: [Int]) ->
+          (ofoldl' (applyFun2 f) a mono) ==
+          (ofoldl' (applyFun2 f) a $ listToTrans mono)
+    describe "otoList" $ do
+      prop "is equivalent to list" $
+        \(mono :: [Int]) ->
+          otoList (listToTrans mono) == mono
+    describe "oall" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (mono :: [Int]) ->
+          (oall f mono) ==
+          (oall f $ listToTrans mono)
+    describe "oany" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (mono :: [Int]) ->
+          (oany f mono) ==
+          (oany f $ listToTrans mono)
+    describe "onull" $ do
+      prop "is equivalent to list" $
+        \(mono :: [Int]) ->
+          (onull mono) ==
+          (onull $ listToTrans mono)
+    describe "olength" $ do
+      prop "is equivalent to list" $
+        \(mono :: [Int]) ->
+          (olength mono) ==
+          (olength $ listToTrans mono)
+    describe "olength64" $ do
+      prop "is equivalent to list" $
+        \(mono :: [Int]) ->
+          (olength64 mono) ==
+          (olength64 $ listToTrans mono)
+    describe "ocompareLength" $ do
+      prop "is equivalent to list" $
+        \(i :: Integer) (mono :: [String]) ->
+          (ocompareLength mono i) ==
+          (ocompareLength (listToTrans mono) i)
+    describe "otraverse_" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (mono :: [Int]) ->
+          (otraverse_ (f :: Int -> Maybe String) mono) ==
+          (otraverse_ f $ listToTrans mono)
+    describe "ofor_" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (mono :: [Int]) ->
+          (ofor_ mono (f :: Int -> Maybe String)) ==
+          (ofor_ (listToTrans mono) f)
+    describe "omapM_" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (mono :: [Int]) ->
+          (omapM_ (f :: Int -> Maybe ()) mono) ==
+          (omapM_ f (listToTrans mono))
+    describe "oforM_" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (mono :: [Int]) ->
+          (ofor_ mono (f :: Int -> Maybe ())) ==
+          (ofor_ (listToTrans mono) f)
+    describe "ofoldlM" $ do
+      prop "is equivalent to list" $
+        \f (a :: String) (mono :: [Int]) ->
+          (ofoldlM (applyFun2 f) a mono :: Maybe String) ==
+          (ofoldlM (applyFun2 f) a (listToTrans mono))
+    describe "ofoldMap1Ex" $ do
+      it "is equivalent to list" $ again $ \(Fun _ f) (mono :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (ofoldMap1Ex f mono :: String)
+          <*> tryEvaluate (ofoldMap1Ex f (listToTrans mono))
+    describe "ofoldr1Ex" $ do
+      it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (ofoldr1Ex (applyFun2 f) mono)
+          <*> tryEvaluate (ofoldr1Ex (applyFun2 f) (listToTrans mono))
+    describe "ofoldl1Ex'" $ do
+      it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (ofoldl1Ex' (applyFun2 f) mono)
+          <*> tryEvaluate (ofoldl1Ex' (applyFun2 f) (listToTrans mono))
+    describe "headEx" $ do
+      it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (headEx mono)
+          <*> tryEvaluate (headEx (listToTrans mono))
+    describe "lastEx" $ do
+      it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (lastEx mono)
+          <*> tryEvaluate (lastEx (listToTrans mono))
+    describe "unsafeHead" $ do
+      it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (unsafeHead mono)
+          <*> tryEvaluate (unsafeHead (listToTrans mono))
+    describe "unsafeLast" $ do
+      it "is equivalent to list" $ again $ \(mono :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (unsafeLast mono)
+          <*> tryEvaluate (unsafeLast (listToTrans mono))
+    describe "maximumByEx" $ do
+      it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (maximumByEx (applyFun2 f) mono)
+          <*> tryEvaluate (maximumByEx (applyFun2 f) (listToTrans mono))
+    describe "minimumByEx" $ do
+      it "is equivalent to list" $ again $ \f (mono :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (minimumByEx (applyFun2 f) mono)
+          <*> tryEvaluate (minimumByEx (applyFun2 f) (listToTrans mono))
+
+#if MIN_VERSION_mono_traversable(1,0,5)
+    describe "oelem" $ do
+      prop "is equivalent to list" $
+        \(a :: Int) (mono :: [Int]) ->
+          (oelem a mono) ==
+          (oelem a (listToTrans mono))
+    describe "onotElem" $ do
+      prop "is equivalent to list" $
+        \(a :: Int) (mono :: [Int]) ->
+          (onotElem a mono) ==
+          (onotElem a (listToTrans mono))
+#endif
+
+  describe "MonoPointed" $ do
+    describe "opoint" $ do
+      prop "is equivalent to list" $
+        \(a :: Int) ->
+          (opoint a) ==
+          (toList $ opoint a)
+
+  describe "SemiSequence" $ do
+    describe "intersperse" $ do
+      prop "is equivalent to list" $
+        \(seq :: [Int]) a ->
+          (intersperse a seq) ==
+          (toList $ intersperse a $ listToTrans seq)
+    describe "reverse" $ do
+      prop "is equivalent to list" $
+        \(seq :: [Int]) ->
+          (reverse seq) ==
+          (toList $ reverse $ listToTrans seq)
+    describe "sortBy" $ do
+      prop "is equivalent to list" $
+        \f (seq :: [Int]) ->
+          (sortBy (applyFun2 f) seq) ==
+          (toList $ sortBy (applyFun2 f) $ listToTrans seq)
+    describe "cons" $ do
+      prop "is equivalent to list" $
+        \a (seq :: [Int]) ->
+          (cons a seq) ==
+          (toList $ cons a $ listToTrans seq)
+    describe "snoc" $ do
+      prop "is equivalent to list" $
+        \a (seq :: [Int]) ->
+          (snoc seq a) ==
+          (toList $ snoc (listToTrans seq) a)
+
+  describe "MonoTraversable" $ do
+    describe "otraverse" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (mono :: [Int]) ->
+          (otraverse (f :: Int -> Maybe Int) mono) ==
+          (toList <$> otraverse f (listToTrans mono))
+    describe "omapM" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (mono :: [Int]) ->
+          (otraverse (f :: Int -> Maybe Int) mono) ==
+          (toList <$> otraverse f (listToTrans mono))
+
+  describe "IsSequence" $ do
+    describe "fromList" $ do
+      prop "is equivalent to list" $
+        \(seq :: [Int]) ->
+          (toList $ fromList seq) == seq
+#if MIN_VERSION_mono_traversable(1,0,2)
+    describe "lengthIndex" $ do
+      prop "is equivalent to list" $
+        \(seq :: [Int]) ->
+          (lengthIndex seq) ==
+          (lengthIndex (listToTrans seq))
+#endif
+    describe "break" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (seq :: [Int]) ->
+          (break f seq) ==
+          (let (a,b) = break f (listToTrans seq) in (toList a, toList b))
+    describe "span" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (seq :: [Int]) ->
+          (span f seq) ==
+          (let (a,b) = span f (listToTrans seq) in (toList a, toList b))
+    describe "dropWhile" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (seq :: [Int]) ->
+          (dropWhile f seq) ==
+          (toList $ dropWhile f $ listToTrans seq)
+    describe "takeWhile" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (seq :: [Int]) ->
+          (takeWhile f seq) ==
+          (toList $ takeWhile f $ listToTrans seq)
+    describe "splitAt" $ do
+      prop "is equivalent to list" $
+        \n (seq :: [Int]) ->
+          (splitAt n seq) ==
+          (let (a,b) = splitAt n (listToTrans seq) in (toList a, toList b))
+    describe "unsafeSplitAt" $ do
+      prop "is equivalent to list" $
+        \n (seq :: [Int]) ->
+          (unsafeSplitAt n seq) ==
+          (let (a,b) = unsafeSplitAt n (listToTrans seq) in (toList a, toList b))
+    describe "take" $ do
+      prop "is equivalent to list" $
+        \n (seq :: [Int]) ->
+          (take n seq) ==
+          (toList $ take n $ fromList seq)
+    describe "unsafeTake" $ do
+      prop "is equivalent to list" $
+        \n (seq :: [Int]) ->
+          (unsafeTake n seq) ==
+          (toList $ unsafeTake n $ fromList seq)
+    describe "drop" $ do
+      prop "is equivalent to list" $
+        \n (seq :: [Int]) ->
+          (drop n seq) ==
+          (toList $ drop n $ fromList seq)
+    describe "unsafeDrop" $ do
+      prop "is equivalent to list" $
+        \n (seq :: [Int]) ->
+          (unsafeDrop n seq) ==
+          (toList $ unsafeDrop n $ fromList seq)
+#if MIN_VERSION_mono_traversable(1,0,4)
+    describe "dropEnd" $ do
+      prop "is equivalent to list" $
+        \n (seq :: [Int]) ->
+          (dropEnd n seq) ==
+          (toList $ dropEnd n $ fromList seq)
+#endif
+    describe "partition" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (seq :: [Int]) ->
+          (partition f seq) ==
+          (let (a, b) = partition f (listToTrans seq) in (toList a, toList b))
+    describe "uncons" $ do
+      prop "is equivalent to list" $
+        \(seq :: [Int]) ->
+          (uncons seq) ==
+          (second toList <$> uncons (listToTrans seq))
+    describe "unsnoc" $ do
+      prop "is equivalent to list" $
+        \(seq :: [Int]) ->
+          (unsnoc seq) ==
+          (first toList <$> unsnoc (listToTrans seq))
+    describe "filter" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (seq :: [Int]) ->
+          (filter f seq) ==
+          (toList $ filter f $ listToTrans seq)
+    describe "filterM" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (seq :: [Int]) ->
+          (filterM (f :: Int -> Maybe Bool) seq) ==
+          (toList <$> filterM f (listToTrans seq))
+    describe "replicate" $ do
+      prop "is equivalent to list" $
+        \n (a :: Int) ->
+          (replicate n a) ==
+          (toList $ replicate n a)
+    describe "replicateM" $ do
+      prop "is equivalent to list" $
+        \n (ma :: Maybe Int) ->
+          (replicateM n ma) ==
+          (toList <$> replicateM n ma)
+    describe "groupBy" $ do
+      prop "is equivalent to list" $
+        \f (seq :: [Int]) ->
+          (groupBy (applyFun2 f) seq) ==
+          (map toList $ groupBy (applyFun2 f) $ listToTrans seq)
+    describe "groupAllOn" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (seq :: [Int]) ->
+          (groupAllOn (f :: Int -> String) seq) ==
+          (map toList $ groupAllOn f $ listToTrans seq)
+    describe "subsequences" $ do
+      modifyMaxSize (const 10) $ prop "is equivalent to list" $
+        \(seq :: [Int]) ->
+          (subsequences seq) ==
+          (map toList $ subsequences $ listToTrans seq)
+    describe "permutations" $ do
+      modifyMaxSize (const 10) $ prop "is equivalent to list" $
+        \(seq :: [Int]) ->
+          (permutations seq) ==
+          (map toList $ permutations $ listToTrans seq)
+    describe "tailEx" $ do
+      it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (tailEx seq)
+          <*> tryEvaluate (toList $ tailEx $ listToTrans seq)
+    describe "tailMay" $ do
+      prop "is equivalent to list" $
+        \(seq :: [Int]) ->
+          (tailMay seq) ==
+          (fmap toList $ tailMay $ listToTrans seq)
+    describe "initEx" $ do
+      it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (initEx seq)
+          <*> tryEvaluate (toList $ initEx $ listToTrans seq)
+    describe "initMay" $ do
+      prop "is equivalent to list" $
+        \(seq :: [Int]) ->
+          (initMay seq) ==
+          (fmap toList $ initMay $ listToTrans seq)
+    describe "unsafeTail" $ do
+      it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (unsafeTail seq)
+          <*> tryEvaluate (toList $ unsafeTail $ listToTrans seq)
+    describe "unsafeInit" $ do
+      it "is equivalent to list" $ again $ \(seq :: [Int]) -> ioProperty $
+        exceptionableEq
+          <$> tryEvaluate (unsafeInit seq)
+          <*> tryEvaluate (toList $ unsafeInit $ listToTrans seq)
+    describe "index" $ do
+      prop "is equivalent to list" $
+        \(seq :: [Int]) n ->
+          (index seq n) ==
+          (index (listToTrans seq) n)
+    describe "indexEx" $ do
+      it "is equivalent to list" $ again $ \(seq :: [Int]) n -> ioProperty $
+        exceptionableEq <$> tryEvaluate (indexEx seq n) <*> tryEvaluate (indexEx (listToTrans seq) n)
+    describe "unsafeIndex" $ do
+      it "is equivalent to list" $ again $ \(seq :: [Int]) n -> ioProperty $
+        exceptionableEq <$> tryEvaluate (unsafeIndex seq n) <*> tryEvaluate (unsafeIndex (listToTrans seq) n)
+
+    describe "splitWhen" $ do
+      prop "is equivalent to list" $
+        \(Fun _ f) (seq :: [Int]) ->
+          (splitWhen f seq) ==
+          (fmap toList $ splitWhen f $ listToTrans seq)
+
+listToTrans :: [a] -> Transaction a
+listToTrans = fromList
diff --git a/transaction.cabal b/transaction.cabal
--- a/transaction.cabal
+++ b/transaction.cabal
@@ -1,8 +1,8 @@
 name:                transaction
-version:             0.1.0.0
+version:             0.1.1.0
 synopsis:            Monadic representation of transactions.
 description:
-    Monadic representation of transactions.
+    Monadic representation of transactions. Alike `List`, but can be declared with `do` notations.
 homepage:            https://github.com/arowM/haskell-transaction#readme
 license:             MIT
 license-file:        LICENSE
@@ -18,6 +18,7 @@
   hs-source-dirs:      src
   exposed-modules:     Data.Transaction
   build-depends:       base >= 4.9 && < 5
+                     , mono-traversable
   default-language:    Haskell2010
   default-extensions:  OverloadedStrings
                      , RecordWildCards
@@ -31,6 +32,9 @@
   hs-source-dirs:      test
   main-is:             Spec.hs
   build-depends:       base
+                     , hspec >= 2.5 && < 3
+                     , mono-traversable
+                     , QuickCheck >= 2.11 && < 3
                      , transaction
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N
   default-language:    Haskell2010
