diff --git a/Data/AhoCorasick.hs b/Data/AhoCorasick.hs
--- a/Data/AhoCorasick.hs
+++ b/Data/AhoCorasick.hs
@@ -20,6 +20,7 @@
 import           Data.Maybe
 import           Data.Vector         (Vector)
 import qualified Data.Vector         as V
+import qualified Data.Vector.Mutable as MV
 import           GHC.Generics        (Generic)
 
 
@@ -30,8 +31,6 @@
 type Output v = Vector [(Int, v)]
 
 type GotoMap a   = HashMap State (HashMap a State)
-type FailureMap  = HashMap State State
-type OutputMap v = HashMap State [(Int, v)]
 
 newtype State = State Int
               deriving (Eq, Generic)
@@ -43,32 +42,21 @@
     } deriving (Show)
 
 construct :: (Eq a, Hashable a) => [[a]] -> ACMachine a [a]
-construct ps = ACMachine (toGotoArray n gotoMap) (toFailureArray n failureMap) (toOutputArray n outputMap)
-  where
-    (m, gotoMap) = buildGoto ps
-    n = m + 1
-    failureMap = buildFailure gotoMap
-    outputMap = buildOutput pvs gotoMap failureMap
-    pvs = zip ps ps
+construct ps = constructWithValues $ zip ps ps
 
 constructWithValues :: (Eq a, Hashable a) => [([a], v)] -> ACMachine a v
-constructWithValues pvs = ACMachine (toGotoArray n gotoMap) (toFailureArray n failureMap) (toOutputArray n outputMap)
+constructWithValues pvs = ACMachine g f o
   where
     (m, gotoMap) = buildGoto ps
     n = m + 1
-    failureMap = buildFailure gotoMap
-    outputMap = buildOutput pvs gotoMap failureMap
+    g = toGotoArray n gotoMap
+    f = buildFailure g
+    o = buildOutput pvs g f
     ps = map fst pvs
 
 toGotoArray :: Int -> GotoMap a -> Goto a
 toGotoArray n m = V.generate n (fromMaybe Map.empty . flip Map.lookup m . State)
 
-toFailureArray :: Int -> FailureMap -> Failure
-toFailureArray n m = V.generate n (fromMaybe (error "failure: ") . flip Map.lookup m . State)
-
-toOutputArray :: Int -> OutputMap v -> Output v
-toOutputArray n m = V.generate n (fromMaybe [] . flip Map.lookup m . State)
-
 root :: State
 root = State 0
 
@@ -85,25 +73,33 @@
 step (ACMachine g f o) x s = (s', output s')
   where
     s' = head $ mapMaybe (flip goto x) $ iterate failure s
-    goto (State 0) x' = (Map.lookup x' $ g V.! 0) <|> Just root
-    goto (State i) x' = Map.lookup x' $ g V.! i
+    goto (State 0) x' = Map.lookup x' (g V.! 0) <|> Just root
+    goto (State i) x' = Map.lookup x' (g V.! i)
     failure (State i) = f V.! i
     output (State i) = o V.! i
 
-buildOutput :: (Eq a, Hashable a) => [([a], v)] -> GotoMap a -> FailureMap -> OutputMap v
-buildOutput pvs gotoMap failureMap = foldl' build o0 $ tail $ toBFList gotoMap
+buildOutput :: (Eq a, Hashable a) => [([a], v)] -> Goto a -> Failure -> Output v
+buildOutput pvs g f = V.create $ do
+    o <- MV.replicate (V.length g) []
+    forM_ (map (fromJust . toKV) pvs) $ \(State i, vs) ->
+        MV.write o i vs
+    forM_ (tail $ toBFList g) $ \(State i) -> do
+        let ts = Map.toList (g V.! i)
+        forM_ ts $ \(_, s'@(State j)) -> do
+            let (State k) = failure s'
+            vs <- MV.read o j
+            vsf <- MV.read o k
+            let vs' = vsf `seq` vs ++ vsf
+            MV.write o j vs'
+    return o
   where
-    build o s = foldl' (\a (_, s') -> let vs = lookupDefault [] (failure s') a in vs `seq` Map.insertWith (flip (++)) s' vs a) o ts
-      where
-        ts = Map.toList $ lookupDefault Map.empty s gotoMap
-    failure = fromMaybe (error "failure: ") . flip Map.lookup failureMap
-    o0 = Map.fromList $ map (fromJust . toKV) pvs
+    failure (State i) = f V.! i
     toKV (p, v) = do
-        s <- finalState gotoMap root p
+        s <- finalState g root p
         return (s, [(length p, v)])
 
-finalState :: (Eq a, Hashable a) => GotoMap a -> State -> [a] -> Maybe State
-finalState m = foldM (\s x -> Map.lookup s m >>= Map.lookup x)
+finalState :: (Eq a, Hashable a) => Goto a -> State -> [a] -> Maybe State
+finalState g = foldM (\(State i) x -> Map.lookup x (g V.! i))
 
 buildGoto :: (Eq a, Hashable a) => [[a]] -> (Int, GotoMap a)
 buildGoto = foldl' (flip extend) (0, Map.empty)
@@ -123,53 +119,46 @@
       where
         sm = fromMaybe Map.empty $ Map.lookup s m
 
-buildFailure :: (Eq a, Hashable a) => GotoMap a -> FailureMap
-buildFailure m = foldl' build Map.empty $ toBFList m
+buildFailure :: (Eq a, Hashable a) => Goto a -> Failure
+buildFailure g = V.create $ do
+    f <- MV.new (V.length g)
+    MV.write f 0 (error "Referencing the failure transition from the root node.")
+    forM_ (toBFList g) $ \s@(State i) -> do
+        let ts = Map.toList (g V.! i)
+        forM_ ts $ \(x, State j) -> do
+            s' <- failureState f s x
+            MV.write f j s'
+    return f
   where
-    build f s = foldl' (\a (x, s') -> Map.insert s' (failureState f s x) a) f ts
-      where
-        ts = Map.toList $ lookupDefault Map.empty s m
-    failureState _ (State 0) _ = root
-    failureState f s x = head $ mapMaybe (flip goto x) $ iterate failure (failure s)
+    failureState _ (State 0) _ = return root
+    failureState f s x = go =<< failure s
       where
-        failure = fromMaybe (error "failure: ") . flip Map.lookup f
-    goto (State 0) x = (Map.lookup root m >>= Map.lookup x) <|> Just root
-    goto s x = Map.lookup s m >>= Map.lookup x
-
-toBFList :: GotoMap a -> [State]
-toBFList m = ss0
-  where
-    ss0 = root : go 1 ss0
-    go 0 _ = []
-    go n (s:ss) = case Map.lookup s m of
-        Nothing -> go (n - 1) ss
-        Just sm -> children ++ go (n - 1 + Map.size sm) ss
-          where
-            children = Map.elems sm
-    go _ _ = error "toBFList: invalid state"
+        go s' = case goto s' x of
+            Nothing -> go =<< failure s'
+            Just s'' -> return s''
+        failure (State i) = MV.read f i
+    goto (State 0) x = Map.lookup x (g V.! 0) <|> Just root
+    goto (State i) x = Map.lookup x (g V.! i)
 
-toBFList' :: Goto a -> [State]
-toBFList' v = ss0
+toBFList :: Goto a -> [State]
+toBFList g = ss0
   where
     ss0 = root : go 1 ss0
     go 0 _ = []
-    go n ((State i):ss) = children ++ go (n - 1 + Map.size sm) ss
+    go n (State i : ss) = children ++ go (n - 1 + Map.size sm) ss
       where
-        sm = v V.! i
+        sm = g V.! i
         children = Map.elems sm
     go _ _ = error "toBFList: invalid state"
 
-lookupDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v
-lookupDefault def k m = fromMaybe def $ Map.lookup k m
-
 renderGraph :: ACMachine Char [Char] -> String
 renderGraph (ACMachine g f o) =
     graph "digraph" $ statements [
           attr "graph" [("rankdir", "LR")]
-        , statements $ map state (toBFList' g)
+        , statements $ map state (toBFList g)
         , statements $ map stateWithOutput $ filter (not . null . snd) $ zip (map State [0..]) (V.toList o)
-        , statements $ map (\s@(State i) -> statements $ map (uncurry $ transEdge s) $ Map.toList $ g V.! i) (toBFList' g)
-        , statements $ map (\s@(State i) -> failEdge s $ f V.! i) (tail $ toBFList' g)
+        , statements $ map (\s@(State i) -> statements $ map (uncurry $ transEdge s) $ Map.toList $ g V.! i) (toBFList g)
+        , statements $ map (\s@(State i) -> failEdge s $ f V.! i) (tail $ toBFList g)
         ]
   where
     statements = intercalate " "
diff --git a/ac-machine.cabal b/ac-machine.cabal
--- a/ac-machine.cabal
+++ b/ac-machine.cabal
@@ -1,5 +1,5 @@
 name:                ac-machine
-version:             0.2.0.2
+version:             0.2.0.4
 synopsis:            Aho-Corasick string matching algorithm in Haskell
 description:         An implementation of the Aho-Corasick string matching algorithm written in Haskell.
 license:             BSD3
@@ -13,9 +13,12 @@
 
 library
   exposed-modules:     Data.AhoCorasick
-  other-extensions:    DeriveGeneric
-  build-depends:       base >=4.6 && <4.7, hashable >=1.2 && <1.3, unordered-containers >=0.2 && <0.3, vector >=0.10 && <0.11
+  build-depends:       base                 >=4.6  && <4.7
+                     , hashable             >=1.2  && <1.3
+                     , unordered-containers >=0.2  && <0.3
+                     , vector               >=0.10 && <0.11
   default-language:    Haskell2010
+  ghc-options:         -Wall
 
 source-repository head
   type:     git
