diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # ChangeLog for yaml
 
+## 0.10.1
+
+* Avoid incurring a `semigroups` dependency on recent GHCs.
+* Fix a space leak that was introduced with `0.10.0` [#147](https://github.com/snoyberg/yaml/issues/147)
+
 ## 0.10.0
 
 * Add `decodeFileWithWarnings` which returns warnings for duplicate fields
diff --git a/src/Data/Yaml/Internal.hs b/src/Data/Yaml/Internal.hs
--- a/src/Data/Yaml/Internal.hs
+++ b/src/Data/Yaml/Internal.hs
@@ -2,6 +2,7 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE PatternGuards #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE BangPatterns #-}
 module Data.Yaml.Internal
     (
       ParseException(..)
@@ -22,7 +23,8 @@
 import Control.Exception
 import Control.Monad (when, unless)
 import Control.Monad.Trans.Resource (ResourceT, runResourceT)
-import Control.Monad.RWS
+import Control.Monad.State.Strict
+import Control.Monad.Reader
 import Data.Aeson
 import Data.Aeson.Internal (JSONPath, JSONPathElement(..))
 import Data.Aeson.Types hiding (parse)
@@ -112,34 +114,45 @@
     ]
   CyclicIncludes -> "Cyclic includes"
 
-defineAnchor :: Value -> String -> ConduitM e o Parse ()
-defineAnchor value name = modify $ Map.insert name value
+defineAnchor :: Value -> String -> ReaderT JSONPath (ConduitM e o Parse) ()
+defineAnchor value name = modify (modifyAnchors $ Map.insert name value)
+  where
+    modifyAnchors :: (Map String Value -> Map String Value) -> ParseState -> ParseState
+    modifyAnchors f st =  st {parseStateAnchors = f (parseStateAnchors st)}
 
-lookupAnchor :: String -> ConduitM e o Parse (Maybe Value)
-lookupAnchor name = gets (Map.lookup name)
+lookupAnchor :: String -> ReaderT JSONPath (ConduitM e o Parse) (Maybe Value)
+lookupAnchor name = gets (Map.lookup name . parseStateAnchors)
 
 data Warning = DuplicateKey JSONPath
     deriving (Eq, Show)
 
-addWarning :: Warning -> ConduitM e o Parse ()
-addWarning = tell . return
+addWarning :: Warning -> ReaderT JSONPath (ConduitM e o Parse) ()
+addWarning w = modify (modifyWarnings (w :))
+  where
+    modifyWarnings :: ([Warning] -> [Warning]) -> ParseState -> ParseState
+    modifyWarnings f st =  st {parseStateWarnings = f (parseStateWarnings st)}
 
-type Parse = RWST JSONPath [Warning] (Map String Value) (ResourceT IO)
+data ParseState = ParseState {
+  parseStateAnchors :: Map String Value
+, parseStateWarnings :: [Warning]
+}
 
-requireEvent :: Event -> ConduitM Event o Parse ()
+type Parse = StateT ParseState (ResourceT IO)
+
+requireEvent :: Event -> ReaderT JSONPath (ConduitM Event o Parse) ()
 requireEvent e = do
-    f <- CL.head
+    f <- lift CL.head
     unless (f == Just e) $ liftIO $ throwIO $ UnexpectedEvent f $ Just e
 
-parse :: ConduitM Event o Parse Value
+parse :: ReaderT JSONPath (ConduitM Event o Parse) Value
 parse = do
-    streamStart <- CL.head
+    streamStart <- lift CL.head
     case streamStart of
         Nothing ->
             -- empty string input
             return Null
         Just EventStreamStart -> do
-            documentStart <- CL.head
+            documentStart <- lift CL.head
             case documentStart of
                 Just EventStreamEnd ->
                     -- empty file input, comment only string/file input
@@ -153,7 +166,7 @@
         _ -> liftIO $ throwIO $ UnexpectedEvent streamStart Nothing
 
 parseScalar :: ByteString -> Anchor -> Style -> Tag
-            -> ConduitM Event o Parse Text
+            -> ReaderT JSONPath (ConduitM Event o Parse) Text
 parseScalar v a style tag = do
     let res = decodeUtf8With lenientDecode v
     mapM_ (defineAnchor (textToValue style tag res)) a
@@ -185,9 +198,9 @@
         isOctalDigit c = (c >= '0' && c <= '7')
         step a c = (a `shiftL` 3) .|. fromIntegral (ord c - 48)
 
-parseO :: ConduitM Event o Parse Value
+parseO :: ReaderT JSONPath (ConduitM Event o Parse) Value
 parseO = do
-    me <- CL.head
+    me <- lift CL.head
     case me of
         Just (EventScalar v tag style a) -> textToValue style tag <$> parseScalar v a style tag
         Just (EventSequenceStart _ _ a) -> parseS 0 a id
@@ -202,12 +215,12 @@
 parseS :: Int
        -> Y.Anchor
        -> ([Value] -> [Value])
-       -> ConduitM Event o Parse Value
-parseS n a front = do
-    me <- CL.peek
+       -> ReaderT JSONPath (ConduitM Event o Parse) Value
+parseS !n a front = do
+    me <- lift CL.peek
     case me of
         Just EventSequenceEnd -> do
-            CL.drop 1
+            lift $ CL.drop 1
             let res = Array $ V.fromList $ front []
             mapM_ (defineAnchor res) a
             return res
@@ -218,9 +231,9 @@
 parseM :: Set Text
        -> Y.Anchor
        -> M.HashMap Text Value
-       -> ConduitM Event o Parse Value
+       -> ReaderT JSONPath (ConduitM Event o Parse) Value
 parseM mergedKeys a front = do
-    me <- CL.head
+    me <- lift CL.head
     case me of
         Just EventMappingEnd -> do
             let res = Object front
@@ -247,7 +260,7 @@
               if s == pack "<<"
                          then case o of
                                   Object l  -> return (merge l)
-                                  Array l -> return $ merge $ foldl mergeObjects M.empty $ V.toList l
+                                  Array l -> return $ merge $ foldl' mergeObjects M.empty $ V.toList l
                                   _          -> al
                          else al
             parseM mergedKeys' a al'
@@ -263,28 +276,28 @@
     -- This used to be tryAny, but the fact is that catching async
     -- exceptions is fine here. We'll rethrow them immediately in the
     -- otherwise clause.
-    x <- try $ runResourceT $ evalRWST (runConduit $ src .| parse) [] Map.empty
+    x <- try $ runResourceT $ runStateT (runConduit $ src .| runReaderT parse []) (ParseState Map.empty [])
     case x of
         Left e
             | Just pe <- fromException e -> return $ Left pe
             | Just ye <- fromException e -> return $ Left $ InvalidYaml $ Just (ye :: YamlException)
             | otherwise -> throwIO e
-        Right (y, warnings) -> return $ Right (warnings, parseEither parseJSON y)
+        Right (y, st) -> return $ Right (parseStateWarnings st, parseEither parseJSON y)
 
 decodeHelper_ :: FromJSON a
               => ConduitM () Event Parse ()
               -> IO (Either ParseException ([Warning], a))
 decodeHelper_ src = do
-    x <- try $ runResourceT $ evalRWST (runConduit $ src .| parse) [] Map.empty
+    x <- try $ runResourceT $ runStateT (runConduit $ src .| runReaderT parse []) (ParseState Map.empty [])
     return $ case x of
         Left e
             | Just pe <- fromException e -> Left pe
             | Just ye <- fromException e -> Left $ InvalidYaml $ Just (ye :: YamlException)
             | otherwise -> Left $ OtherParseException e
-        Right (y, warnings) -> either
+        Right (y, st) -> either
             (Left . AesonException)
             Right
-            ((,) warnings <$> parseEither parseJSON y)
+            ((,) (parseStateWarnings st) <$> parseEither parseJSON y)
 
 -- | Strings which must be escaped so as not to be treated as non-string scalars.
 specialStrings :: HashSet.HashSet Text
diff --git a/test/Data/Yaml/IncludeSpec.hs b/test/Data/Yaml/IncludeSpec.hs
--- a/test/Data/Yaml/IncludeSpec.hs
+++ b/test/Data/Yaml/IncludeSpec.hs
@@ -4,6 +4,7 @@
 
 import           Test.Hspec
 import           Data.List (isPrefixOf)
+import qualified Data.ByteString.Lazy as LB
 import           Data.Aeson
 import           Data.Aeson.Internal (JSONPathElement(..))
 import           Data.Yaml (ParseException(InvalidYaml))
@@ -51,6 +52,15 @@
     context "when file does not exist" $ do
       it "throws Left (InvalidYaml (Just (YamlException \"Yaml file not found: ...\")))" $ do
         (decodeFile "./does_not_exist.yaml" :: IO (Maybe Value)) `shouldThrow` isYamlFileNotFoundException
+
+    context "with a 1K stack size limit" $ around_ inTempDirectory $ do
+      context "with a large list" $ do
+        it "succeeds" $ do
+          let
+            xs :: [Value]
+            xs = replicate 5000 (Number 23)
+          LB.writeFile "foo.yaml" (encode xs)
+          decodeFile "foo.yaml" `shouldReturn` Just xs
 
   describe "decodeFileEither" $ do
     context "when file does not exist" $ do
diff --git a/yaml.cabal b/yaml.cabal
--- a/yaml.cabal
+++ b/yaml.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: a82d0ad23c31e4d461a49236c789475df6276479abe75c53c04f33be563b808f
+-- hash: 514c53ba5a36230ee3cda22bed82857fb3fe0ae4227b17ad757b65a87473b77a
 
 name:           yaml
-version:        0.10.0
+version:        0.10.1
 synopsis:       Support for parsing and rendering YAML documents.
 description:    README and API documentation are available at <https://www.stackage.org/package/yaml>
 category:       Data
@@ -95,12 +95,14 @@
     , mtl
     , resourcet >=0.3 && <1.3
     , scientific
-    , semigroups
     , template-haskell
     , text
     , transformers >=0.1
     , unordered-containers
     , vector
+  if !impl(ghc >= 8.0)
+    build-depends:
+        semigroups
   if flag(no-unicode)
     cpp-options: -D__NO_UNICODE__
   if !(flag(system-libyaml))
@@ -140,12 +142,14 @@
     , mtl
     , resourcet >=0.3 && <1.3
     , scientific
-    , semigroups
     , template-haskell
     , text
     , transformers >=0.1
     , unordered-containers
     , vector
+  if !impl(ghc >= 8.0)
+    build-depends:
+        semigroups
   if flag(no-examples)
     buildable: False
   else
@@ -172,13 +176,15 @@
     , mtl
     , resourcet >=0.3 && <1.3
     , scientific
-    , semigroups
     , template-haskell
     , text
     , transformers >=0.1
     , unordered-containers
     , vector
     , yaml
+  if !impl(ghc >= 8.0)
+    build-depends:
+        semigroups
   if flag(no-exe)
     buildable: False
   default-language: Haskell2010
@@ -201,13 +207,15 @@
     , mtl
     , resourcet >=0.3 && <1.3
     , scientific
-    , semigroups
     , template-haskell
     , text
     , transformers >=0.1
     , unordered-containers
     , vector
     , yaml
+  if !impl(ghc >= 8.0)
+    build-depends:
+        semigroups
   if flag(no-exe)
     buildable: False
   default-language: Haskell2010
@@ -222,7 +230,7 @@
       Paths_yaml
   hs-source-dirs:
       test
-  ghc-options: -Wall
+  ghc-options: -Wall "-with-rtsopts=-K1K"
   cpp-options: -DTEST
   build-depends:
       HUnit
@@ -241,7 +249,6 @@
     , raw-strings-qq
     , resourcet >=0.3 && <1.3
     , scientific
-    , semigroups
     , template-haskell
     , temporary
     , text
@@ -249,4 +256,7 @@
     , unordered-containers
     , vector
     , yaml
+  if !impl(ghc >= 8.0)
+    build-depends:
+        semigroups
   default-language: Haskell2010
