diff --git a/deque.cabal b/deque.cabal
--- a/deque.cabal
+++ b/deque.cabal
@@ -1,5 +1,5 @@
 name: deque
-version: 0.4.0.1
+version: 0.4.0.2
 synopsis: Double-ended queues
 description:
   Strict and lazy implementations of Double-Ended Queue (aka Dequeue or Deque)
diff --git a/library/Deque/Lazy/Defs.hs b/library/Deque/Lazy/Defs.hs
--- a/library/Deque/Lazy/Defs.hs
+++ b/library/Deque/Lazy/Defs.hs
@@ -144,9 +144,10 @@
 -- |
 -- /O(n)/.
 prepend :: Deque a -> Deque a -> Deque a
-prepend (Deque snocList1 consList1) (Deque snocList2 consList2) = Deque consList3 snocList3 where
-  consList3 = consList1
-  snocList3 = snocList2 ++ foldl' (flip (:)) snocList1 consList2
+prepend (Deque consList1 snocList1) (Deque consList2 snocList2) = let
+  consList = consList1
+  snocList = snocList2 ++ foldl' (flip (:)) snocList1 consList2
+  in Deque consList snocList
 
 -- |
 -- /O(1)/.
@@ -216,11 +217,22 @@
 
 instance Applicative Deque where
   pure a = Deque [] [a]
-  fs <*> as = fromList (toList fs <*> toList as)
+  (<*>) (Deque fnConsList fnSnocList) (Deque argConsList argSnocList) = let
+    consList = let
+      fnStep fn resultConsList = let
+        argStep arg = (:) (fn arg)
+        in foldr argStep (foldr argStep resultConsList (List.reverse argSnocList)) argConsList
+      in foldr fnStep (foldr fnStep [] (List.reverse fnSnocList)) fnConsList 
+    in Deque consList []
 
 instance Monad Deque where
   return = pure
-  m >>= f = fromList (toList m >>= toList . f)
+  (>>=) (Deque aConsList aSnocList) k = let
+    consList = let
+      aStep a accBConsList = case k a of
+        Deque bConsList bSnocList -> bConsList <> List.reverse bSnocList <> accBConsList
+      in foldr aStep (foldr aStep [] (List.reverse aSnocList)) aConsList
+    in Deque consList []
   fail = const mempty
 
 instance Alternative Deque where
diff --git a/library/Deque/Strict/Defs.hs b/library/Deque/Strict/Defs.hs
--- a/library/Deque/Strict/Defs.hs
+++ b/library/Deque/Strict/Defs.hs
@@ -207,10 +207,10 @@
   toList (Deque consList snocList) = foldr (:) (toList (StrictList.reverse snocList)) consList
 
 instance Semigroup (Deque a) where
-  (<>) (Deque snocList1 consList1) (Deque snocList2 consList2) = let
-    consList3 = consList1 <> StrictList.prependReversed snocList1 consList2
-    snocList3 = snocList2
-    in Deque consList3 snocList3
+  (<>) (Deque consList1 snocList1) (Deque consList2 snocList2) = let
+    consList = consList1
+    snocList = snocList2 <> StrictList.prependReversed consList2 snocList1
+    in Deque consList snocList
 
 instance Monoid (Deque a) where
   mempty = Deque StrictList.Nil StrictList.Nil
@@ -228,11 +228,22 @@
 
 instance Applicative Deque where
   pure a = Deque (pure a) StrictList.Nil
-  fs <*> as = fromList (toList fs <*> toList as)
+  (<*>) (Deque fnConsList fnSnocList) (Deque argConsList argSnocList) = let
+    snocList = let
+      fnStep resultSnocList fn = let
+        argStep resultSnocList arg = StrictList.Cons (fn arg) resultSnocList
+        in foldl' argStep (foldl' argStep resultSnocList argConsList) (StrictList.reverse argSnocList)
+      in foldl' fnStep (foldl' fnStep StrictList.Nil fnConsList) (StrictList.reverse fnSnocList)
+    in Deque StrictList.Nil snocList
 
 instance Monad Deque where
   return = pure
-  m >>= f = fromList (toList m >>= toList . f)
+  (>>=) (Deque aConsList aSnocList) k = let
+    snocList = let
+      aStep accBSnocList a = case k a of
+        Deque bConsList bSnocList -> StrictList.prependReversed bConsList (bSnocList <> accBSnocList)
+      in foldl' aStep (foldl' aStep StrictList.Nil aConsList) (StrictList.reverse aSnocList)
+    in Deque StrictList.Nil snocList
   fail = const mempty
 
 instance Alternative Deque where
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -137,9 +137,15 @@
         [] -> []
         _ -> List.init list
       ,
-      testProperty "ap" $ forAll ((,) <$> dequeAndListGen <*> dequeAndListGen) $ \ ((deque1, list1), (deque2, list2)) ->
+      testProperty "<>" $ forAll ((,) <$> dequeAndListGen <*> dequeAndListGen) $ \ ((deque1, list1), (deque2, list2)) ->
+      toList (deque1 <> deque2) === (list1 <> list2)
+      ,
+      testProperty "<*>" $ forAll ((,) <$> dequeAndListGen <*> dequeAndListGen) $ \ ((deque1, list1), (deque2, list2)) ->
       toList ((,) <$> deque1 <*> deque2) === ((,) <$> list1 <*> list2)
       ,
+      testProperty ">>=" $ forAll ((,) <$> dequeAndListKleisliGen <*> dequeAndListGen) $ \ ((dequeK, listK), (deque, list)) ->
+      toList (deque >>= dequeK) === (list >>= listK)
+      ,
       testProperty "foldl'" $ forAll dequeAndListGen $ \ (deque, list) ->
       foldl' (flip (:)) [] deque === foldl' (flip (:)) [] list
       ,
@@ -155,10 +161,12 @@
         consList <- listGen
         snocList <- listGen
         return (fromConsAndSnocLists consList snocList, consList <> List.reverse snocList)
-      kleisliGen :: Gen (Word8 -> [Word8])
-      kleisliGen = do
+      dequeAndListKleisliGen = do
         list <- listGen
-        return $ \ x -> fmap (+ x) list
+        let
+          listK x = fmap (+ x) list
+          dequeK = fromList . listK
+          in return (dequeK, listK)
 
 sizedListGen maxSize = do
   length <- choose (0, maxSize)
@@ -182,7 +190,13 @@
 -------------------------
 
 instance Show (Word8 -> Bool) where
-  show _ = "(Word8 -> Bool) function"
+  show _ = "@(Word8 -> Bool)"
 
 instance Show (Word8 -> [Word8]) where
-  show _ = "(Word8 -> [Word8]) function"
+  show _ = "@(Word8 -> [Word8])"
+
+instance Show (Word8 -> Strict.Deque Word8) where
+  show _ = "@(Word8 -> Deque Word8)"
+
+instance Show (Word8 -> Lazy.Deque Word8) where
+  show _ = "@(Word8 -> Deque Word8)"
