diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,9 @@
+## 0.8.31
+
+* Add `decodeThrow` and `decodeFileThrow` convenience functions.
+* Upgrade libyaml versions
+* Deprecate `decode` and `decodeEither`
+
 ## 0.8.30
 
 * Removed `AppSettings` mentioned in `loadYamlSettings` error message.
diff --git a/Data/Yaml.hs b/Data/Yaml.hs
--- a/Data/Yaml.hs
+++ b/Data/Yaml.hs
@@ -26,8 +26,18 @@
 #else
 module Data.Yaml
 #endif
-    ( -- * Types
-      Value (..)
+    ( -- * Encoding
+      encode
+    , encodeFile
+      -- * Decoding
+    , decodeEither'
+    , decodeFileEither
+    , decodeThrow
+    , decodeFileThrow
+      -- ** More control over decoding
+    , decodeHelper
+      -- * Types
+    , Value (..)
     , Parser
     , Object
     , Array
@@ -55,22 +65,17 @@
       -- * Classes
     , ToJSON (..)
     , FromJSON (..)
-      -- * Encoding/decoding
-    , encode
-    , encodeFile
+      -- * Deprecated
     , decode
     , decodeFile
-      -- ** Better error information
     , decodeEither
-    , decodeEither'
-    , decodeFileEither
-      -- ** More control over decoding
-    , decodeHelper
     ) where
 #if !MIN_VERSION_base(4,8,0)
 import Control.Applicative((<$>))
 #endif
 import Control.Exception
+import Control.Monad.IO.Class (MonadIO, liftIO)
+import Control.Monad.Trans.Resource (MonadThrow, throwM)
 import Data.Aeson
     ( Value (..), ToJSON (..), FromJSON (..), object
     , (.=) , (.:) , (.:?) , (.!=)
@@ -99,11 +104,13 @@
 import Text.Libyaml hiding (encode, decode, encodeFile, decodeFile)
 import qualified Text.Libyaml as Y
 
+-- | Encode a value into its YAML representation.
 encode :: ToJSON a => a -> ByteString
 encode obj = unsafePerformIO $ runConduitRes
     $ CL.sourceList (objToEvents $ toJSON obj)
    .| Y.encode
 
+-- | Encode a value into its YAML representation and save to the given file.
 encodeFile :: ToJSON a => FilePath -> a -> IO ()
 encodeFile fp obj = runConduitRes
     $ CL.sourceList (objToEvents $ toJSON obj)
@@ -160,6 +167,7 @@
 decode bs = unsafePerformIO
           $ either (const Nothing) id
           <$> decodeHelper_ (Y.decode bs)
+{-# DEPRECATED decode "Please use decodeEither or decodeThrow, which provide information on how the decode failed" #-}
 
 decodeFile :: FromJSON a
            => FilePath
@@ -169,7 +177,7 @@
 
 -- | A version of 'decodeFile' which should not throw runtime exceptions.
 --
--- Since 0.8.4
+-- @since 0.8.4
 decodeFileEither
     :: FromJSON a
     => FilePath
@@ -180,16 +188,30 @@
 decodeEither bs = unsafePerformIO
                 $ either (Left . prettyPrintParseException) id
                 <$> decodeHelper (Y.decode bs)
+{-# DEPRECATED decodeEither "Please use decodeEither' or decodeThrow, which provide more useful failures" #-}
 
 -- | More helpful version of 'decodeEither' which returns the 'YamlException'.
 --
--- Since 0.8.3
+-- @since 0.8.3
 decodeEither' :: FromJSON a => ByteString -> Either ParseException a
 decodeEither' = either Left (either (Left . AesonException) Right)
               . unsafePerformIO
               . decodeHelper
               . Y.decode
 
+-- | A version of 'decodeEither'' lifted to MonadThrow
+--
+-- @since 0.8.31
+decodeThrow :: (MonadThrow m, FromJSON a) => ByteString -> m a
+decodeThrow = either throwM return . decodeEither'
+
+-- | A version of 'decodeFileEither' lifted to MonadIO
+--
+-- @since 0.8.31
+decodeFileThrow :: (MonadIO m, FromJSON a) => FilePath -> m a
+decodeFileThrow f = liftIO $ decodeFileEither f >>= either throwIO return
+
+-- | Construct a new 'Value' from a list of 'Value's.
 array :: [Value] -> Value
 array = Array . V.fromList
 
diff --git a/Data/Yaml/Config.hs b/Data/Yaml/Config.hs
--- a/Data/Yaml/Config.hs
+++ b/Data/Yaml/Config.hs
@@ -93,7 +93,10 @@
                     _ -> Null
     goV v = v
 
-    parseValue val = fromMaybe (String val) $ Y.decode $ encodeUtf8 val
+    parseValue val = either
+      (const (String val))
+      id
+      (Y.decodeThrow $ encodeUtf8 val)
 
 -- | Get the actual environment as a @HashMap@ from @Text@ to @Text@.
 --
diff --git a/Data/Yaml/TH.hs b/Data/Yaml/TH.hs
--- a/Data/Yaml/TH.hs
+++ b/Data/Yaml/TH.hs
@@ -30,7 +30,6 @@
 
 import           Data.Yaml hiding (decodeFile)
 
-#if MIN_VERSION_template_haskell(2,9,0)
 -- | Decode a YAML file at compile time. Only available on GHC version @7.8.1@
 -- or higher.
 --
@@ -47,18 +46,13 @@
 decodeFile :: forall a. (Lift a, FromJSON a) => FilePath -> Q (TExp a)
 decodeFile path = do
   addDependentFile path
-  runIO (decodeFileEither path) >>= \case
-    Left err -> fail (prettyPrintParseException err)
-    Right x -> fmap TExp (lift (x :: a))
-#endif
-
-decodeValue :: String -> Either String Value
-decodeValue = decodeEither . encodeUtf8 . T.pack
+  x <- runIO $ decodeFileThrow path
+  fmap TExp (lift (x :: a))
 
 yamlExp :: String -> Q Exp
-yamlExp input = case decodeValue input of
-  Left err -> fail err
-  Right a -> lift a
+yamlExp input = do
+  val <- runIO $ decodeThrow $ encodeUtf8 $ T.pack input
+  lift (val :: Value)
 
 -- | A @QuasiQuoter@ for YAML.
 --
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,8 +1,11 @@
 ## yaml
 
+[![Build Status](https://travis-ci.org/snoyberg/yaml.svg?branch=master)](https://travis-ci.org/snoyberg/yaml)
+[![Build status](https://ci.appveyor.com/api/projects/status/hqy2jketp8m502so/branch/master?svg=true)](https://ci.appveyor.com/project/snoyberg/yaml/branch/master)
+
 Provides support for parsing and emitting Yaml documents.
 
-This package includes the [full libyaml C library version 0.1.7 by Kirill Simonov](http://pyyaml.org/wiki/LibYAML) in the package so you don't need to worry about any non-Haskell dependencies.
+This package includes the [full libyaml C library version 0.2.1 by Kirill Simonov](https://github.com/yaml/libyaml) in the package so you don't need to worry about any non-Haskell dependencies.
 
 The package is broken down into two primary modules. `Data.Yaml` provides a high-level interface based around the JSON datatypes provided by the `aeson` package. `Text.Libyaml` provides a lower-level, streaming interface. For most users, `Data.Yaml` is recommended.
 
diff --git a/examples/Config.hs b/examples/Config.hs
--- a/examples/Config.hs
+++ b/examples/Config.hs
@@ -50,5 +50,6 @@
   parseJSON _ = fail "Expected Object for Config value"
 
 main :: IO ()
-main =
-  print $ (Y.decode configYaml :: Maybe Config)
+main = do
+  config <- Y.decodeThrow configYaml
+  print (config :: Config)
diff --git a/examples/Simple.hs b/examples/Simple.hs
--- a/examples/Simple.hs
+++ b/examples/Simple.hs
@@ -6,7 +6,8 @@
 
 main :: IO ()
 main = do
-  print $ (Y.decode "[1,2,3]" :: Maybe [Integer])
+  res <- Y.decodeThrow "[1,2,3]"
+  print (res :: [Integer])
 
 -- You can go one step further and decode into a custom type by implementing
 -- 'FromJSON' for that type. This is also appropriate where extra
diff --git a/libyaml/LICENSE b/libyaml/LICENSE
--- a/libyaml/LICENSE
+++ b/libyaml/LICENSE
@@ -1,3 +1,4 @@
+Copyright (c) 2017-2018 Ingy döt Net
 Copyright (c) 2006-2016 Kirill Simonov
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/libyaml/api.c b/libyaml/api.c
--- a/libyaml/api.c
+++ b/libyaml/api.c
@@ -81,7 +81,7 @@
 yaml_string_extend(yaml_char_t **start,
         yaml_char_t **pointer, yaml_char_t **end)
 {
-    yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
+    yaml_char_t *new_start = (yaml_char_t *)yaml_realloc((void*)*start, (*end - *start)*2);
 
     if (!new_start) return 0;
 
@@ -101,8 +101,9 @@
 YAML_DECLARE(int)
 yaml_string_join(
         yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
-        yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
+        yaml_char_t **b_start, yaml_char_t **b_pointer, SHIM(yaml_char_t **b_end))
 {
+    UNUSED_PARAM(b_end)
     if (*b_start == *b_pointer)
         return 1;
 
@@ -184,17 +185,17 @@
         goto error;
     if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
         goto error;
-    if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE))
+    if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE, yaml_token_t*))
         goto error;
-    if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(parser, parser->indents, int*))
         goto error;
-    if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(parser, parser->simple_keys, yaml_simple_key_t*))
         goto error;
-    if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(parser, parser->states, yaml_parser_state_t*))
         goto error;
-    if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(parser, parser->marks, yaml_mark_t*))
         goto error;
-    if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(parser, parser->tag_directives, yaml_tag_directive_t*))
         goto error;
 
     return 1;
@@ -250,7 +251,7 @@
 yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
         size_t *size_read)
 {
-    yaml_parser_t *parser = data;
+    yaml_parser_t *parser = (yaml_parser_t *)data;
 
     if (parser->input.string.current == parser->input.string.end) {
         *size_read = 0;
@@ -276,7 +277,7 @@
 yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
         size_t *size_read)
 {
-    yaml_parser_t *parser = data;
+    yaml_parser_t *parser = (yaml_parser_t *)data;
 
     *size_read = fread(buffer, 1, size, parser->input.file);
     return !ferror(parser->input.file);
@@ -362,13 +363,13 @@
         goto error;
     if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
         goto error;
-    if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(emitter, emitter->states, yaml_emitter_state_t*))
         goto error;
-    if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE))
+    if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE, yaml_event_t*))
         goto error;
-    if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(emitter, emitter->indents, int*))
         goto error;
-    if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(emitter, emitter->tag_directives, yaml_tag_directive_t*))
         goto error;
 
     return 1;
@@ -420,7 +421,7 @@
 static int
 yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
 {
-    yaml_emitter_t *emitter = data;
+  yaml_emitter_t *emitter = (yaml_emitter_t *)data;
 
     if (emitter->output.string.size - *emitter->output.string.size_written
             < size) {
@@ -446,7 +447,7 @@
 static int
 yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
 {
-    yaml_emitter_t *emitter = data;
+    yaml_emitter_t *emitter = (yaml_emitter_t *)data;
 
     return (fwrite(buffer, 1, size, emitter->output.file) == size);
 }
@@ -724,7 +725,7 @@
                             /* Valid tag directives are expected. */
 
     if (version_directive) {
-        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
+        version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
         if (!version_directive_copy) goto error;
         version_directive_copy->major = version_directive->major;
         version_directive_copy->minor = version_directive->minor;
@@ -732,7 +733,7 @@
 
     if (tag_directives_start != tag_directives_end) {
         yaml_tag_directive_t *tag_directive;
-        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
+        if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
             goto error;
         for (tag_directive = tag_directives_start;
                 tag_directive != tag_directives_end; tag_directive ++) {
@@ -852,7 +853,7 @@
     }
 
     if (!yaml_check_utf8(value, length)) goto error;
-    value_copy = yaml_malloc(length+1);
+    value_copy = YAML_MALLOC(length+1);
     if (!value_copy) goto error;
     memcpy(value_copy, value, length);
     value_copy[length] = '\0';
@@ -1064,10 +1065,10 @@
             (tag_directives_start == tag_directives_end));
                             /* Valid tag directives are expected. */
 
-    if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error;
+    if (!STACK_INIT(&context, nodes, yaml_node_t*)) goto error;
 
     if (version_directive) {
-        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
+        version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
         if (!version_directive_copy) goto error;
         version_directive_copy->major = version_directive->major;
         version_directive_copy->minor = version_directive->minor;
@@ -1075,7 +1076,7 @@
 
     if (tag_directives_start != tag_directives_end) {
         yaml_tag_directive_t *tag_directive;
-        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
+        if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
             goto error;
         for (tag_directive = tag_directives_start;
                 tag_directive != tag_directives_end; tag_directive ++) {
@@ -1228,7 +1229,7 @@
     }
 
     if (!yaml_check_utf8(value, length)) goto error;
-    value_copy = yaml_malloc(length+1);
+    value_copy = YAML_MALLOC(length+1);
     if (!value_copy) goto error;
     memcpy(value_copy, value, length);
     value_copy[length] = '\0';
@@ -1275,7 +1276,7 @@
     tag_copy = yaml_strdup(tag);
     if (!tag_copy) goto error;
 
-    if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error;
+    if (!STACK_INIT(&context, items, yaml_node_item_t*)) goto error;
 
     SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
             style, mark, mark);
@@ -1320,7 +1321,7 @@
     tag_copy = yaml_strdup(tag);
     if (!tag_copy) goto error;
 
-    if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error;
+    if (!STACK_INIT(&context, pairs, yaml_node_pair_t*)) goto error;
 
     MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
             style, mark, mark);
diff --git a/libyaml/dumper.c b/libyaml/dumper.c
--- a/libyaml/dumper.c
+++ b/libyaml/dumper.c
@@ -245,9 +245,9 @@
 #define ANCHOR_TEMPLATE_LENGTH  16
 
 static yaml_char_t *
-yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id)
+yaml_emitter_generate_anchor(SHIM(yaml_emitter_t *emitter), int anchor_id)
 {
-    yaml_char_t *anchor = yaml_malloc(ANCHOR_TEMPLATE_LENGTH);
+    yaml_char_t *anchor = YAML_MALLOC(ANCHOR_TEMPLATE_LENGTH);
 
     if (!anchor) return NULL;
 
diff --git a/libyaml/emitter.c b/libyaml/emitter.c
--- a/libyaml/emitter.c
+++ b/libyaml/emitter.c
@@ -1002,7 +1002,7 @@
  */
 
 static int
-yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
+yaml_emitter_emit_alias(yaml_emitter_t *emitter, SHIM(yaml_event_t *event))
 {
     if (!yaml_emitter_process_anchor(emitter))
         return 0;
@@ -1087,7 +1087,7 @@
  */
 
 static int
-yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
+yaml_emitter_check_empty_document(SHIM(yaml_emitter_t *emitter))
 {
     return 0;
 }
diff --git a/libyaml/loader.c b/libyaml/loader.c
--- a/libyaml/loader.c
+++ b/libyaml/loader.c
@@ -72,7 +72,7 @@
     assert(document);   /* Non-NULL document object is expected. */
 
     memset(document, 0, sizeof(yaml_document_t));
-    if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(parser, document->nodes, yaml_node_t*))
         goto error;
 
     if (!parser->stream_start_produced) {
@@ -90,7 +90,7 @@
         return 1;
     }
 
-    if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
         goto error;
 
     parser->document = document;
@@ -339,7 +339,7 @@
         if (!tag) goto error;
     }
 
-    if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
+    if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error;
 
     SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
             first_event->data.sequence_start.style,
@@ -402,7 +402,7 @@
         if (!tag) goto error;
     }
 
-    if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
+    if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error;
 
     MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
             first_event->data.mapping_start.style,
diff --git a/libyaml/parser.c b/libyaml/parser.c
--- a/libyaml/parser.c
+++ b/libyaml/parser.c
@@ -605,7 +605,7 @@
                     if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
                         size_t prefix_len = strlen((char *)tag_directive->prefix);
                         size_t suffix_len = strlen((char *)tag_suffix);
-                        tag = yaml_malloc(prefix_len+suffix_len+1);
+                        tag = YAML_MALLOC(prefix_len+suffix_len+1);
                         if (!tag) {
                             parser->error = YAML_MEMORY_ERROR;
                             goto error;
@@ -685,7 +685,7 @@
                 return 1;
             }
             else if (anchor || tag) {
-                yaml_char_t *value = yaml_malloc(1);
+                yaml_char_t *value = YAML_MALLOC(1);
                 if (!value) {
                     parser->error = YAML_MEMORY_ERROR;
                     goto error;
@@ -759,9 +759,8 @@
 
     else if (token->type == YAML_BLOCK_END_TOKEN)
     {
-        yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
         parser->state = POP(parser, parser->states);
-        dummy_mark = POP(parser, parser->marks);
+        (void)POP(parser, parser->marks);
         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
         SKIP_TOKEN(parser);
         return 1;
@@ -869,9 +868,8 @@
 
     else if (token->type == YAML_BLOCK_END_TOKEN)
     {
-        yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
         parser->state = POP(parser, parser->states);
-        dummy_mark = POP(parser, parser->marks);
+        (void)POP(parser, parser->marks);
         MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
         SKIP_TOKEN(parser);
         return 1;
@@ -952,7 +950,6 @@
         yaml_event_t *event, int first)
 {
     yaml_token_t *token;
-    yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
 
     if (first) {
         token = PEEK_TOKEN(parser);
@@ -997,7 +994,7 @@
     }
 
     parser->state = POP(parser, parser->states);
-    dummy_mark = POP(parser, parser->marks);
+    (void)POP(parser, parser->marks);
     SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
     SKIP_TOKEN(parser);
     return 1;
@@ -1104,7 +1101,6 @@
         yaml_event_t *event, int first)
 {
     yaml_token_t *token;
-    yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
 
     if (first) {
         token = PEEK_TOKEN(parser);
@@ -1158,7 +1154,7 @@
     }
 
     parser->state = POP(parser, parser->states);
-    dummy_mark = POP(parser, parser->marks);
+    (void)POP(parser, parser->marks);
     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
     SKIP_TOKEN(parser);
     return 1;
@@ -1212,7 +1208,7 @@
 {
     yaml_char_t *value;
 
-    value = yaml_malloc(1);
+    value = YAML_MALLOC(1);
     if (!value) {
         parser->error = YAML_MEMORY_ERROR;
         return 0;
@@ -1249,7 +1245,7 @@
     } tag_directives = { NULL, NULL, NULL };
     yaml_token_t *token;
 
-    if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
+    if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*))
         goto error;
 
     token = PEEK_TOKEN(parser);
@@ -1270,7 +1266,7 @@
                         "found incompatible YAML document", token->start_mark);
                 goto error;
             }
-            version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
+            version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
             if (!version_directive) {
                 parser->error = YAML_MEMORY_ERROR;
                 goto error;
diff --git a/libyaml/reader.c b/libyaml/reader.c
--- a/libyaml/reader.c
+++ b/libyaml/reader.c
@@ -460,10 +460,10 @@
 
     }
 
-    if (parser->offset >= PTRDIFF_MAX)
+    if (parser->offset >= MAX_FILE_SIZE) {
         return yaml_parser_set_reader_error(parser, "input is too long",
-                PTRDIFF_MAX, -1);
+            parser->offset, -1);
+    }
 
     return 1;
 }
-
diff --git a/libyaml/scanner.c b/libyaml/scanner.c
--- a/libyaml/scanner.c
+++ b/libyaml/scanner.c
@@ -1186,11 +1186,9 @@
 static int
 yaml_parser_decrease_flow_level(yaml_parser_t *parser)
 {
-    yaml_simple_key_t dummy_key;    /* Used to eliminate a compiler warning. */
-
     if (parser->flow_level) {
         parser->flow_level --;
-        dummy_key = POP(parser, parser->simple_keys);
+        (void)POP(parser, parser->simple_keys);
     }
 
     return 1;
@@ -2401,7 +2399,7 @@
     {
         /* Set the handle to '' */
 
-        handle = yaml_malloc(1);
+        handle = YAML_MALLOC(1);
         if (!handle) goto error;
         handle[0] = '\0';
 
@@ -2453,7 +2451,7 @@
             /* Set the handle to '!'. */
 
             yaml_free(handle);
-            handle = yaml_malloc(2);
+            handle = YAML_MALLOC(2);
             if (!handle) goto error;
             handle[0] = '!';
             handle[1] = '\0';
@@ -3164,10 +3162,6 @@
 
                     case '/':
                         *(string.pointer++) = '/';
-                        break;
-
-                    case '\'':
-                        *(string.pointer++) = '\'';
                         break;
 
                     case '\\':
diff --git a/libyaml/yaml.h b/libyaml/yaml.h
--- a/libyaml/yaml.h
+++ b/libyaml/yaml.h
@@ -1091,7 +1091,7 @@
     yaml_error_type_t error;
     /** Error description. */
     const char *problem;
-    /** The byte about which the problem occurred. */
+    /** The byte about which the problem occured. */
     size_t problem_offset;
     /** The problematic value (@c -1 is none). */
     int problem_value;
@@ -1940,8 +1940,8 @@
  *
  * The documen object may be generated using the yaml_parser_load() function
  * or the yaml_document_initialize() function.  The emitter takes the
- * responsibility for the document object and destoys its content after
- * it is emitted. The document object is destroyedeven if the function fails.
+ * responsibility for the document object and destroys its content after
+ * it is emitted. The document object is destroyed even if the function fails.
  *
  * @param[in,out]   emitter     An emitter object.
  * @param[in,out]   document    A document object.
diff --git a/libyaml/yaml_private.h b/libyaml/yaml_private.h
--- a/libyaml/yaml_private.h
+++ b/libyaml/yaml_private.h
@@ -8,16 +8,6 @@
 #include <limits.h>
 #include <stddef.h>
 
-#ifndef _MSC_VER
-#include <stdint.h>
-#else
-#ifdef _WIN64
-#define PTRDIFF_MAX _I64_MAX
-#else
-#define PTRDIFF_MAX INT_MAX
-#endif
-#endif
-
 /*
  * Memory management.
  */
@@ -77,6 +67,17 @@
 #define OUTPUT_RAW_BUFFER_SIZE  (OUTPUT_BUFFER_SIZE*2+2)
 
 /*
+ * The maximum size of a YAML input file.
+ * This used to be PTRDIFF_MAX, but that's not entirely portable
+ * because stdint.h isn't available on all platforms.
+ * It is not entirely clear why this isn't the maximum value
+ * that can fit into the parser->offset field.
+ */
+
+#define MAX_FILE_SIZE (~(size_t)0 / 2)
+
+
+/*
  * The size of other stacks and queues.
  */
 
@@ -89,7 +90,7 @@
  */
 
 #define BUFFER_INIT(context,buffer,size)                                        \
-    (((buffer).start = yaml_malloc(size)) ?                                     \
+  (((buffer).start = (yaml_char_t *)yaml_malloc(size)) ?                        \
         ((buffer).last = (buffer).pointer = (buffer).start,                     \
          (buffer).end = (buffer).start+(size),                                  \
          1) :                                                                   \
@@ -129,7 +130,7 @@
      (value).pointer = (string))
 
 #define STRING_INIT(context,string,size)                                        \
-    (((string).start = yaml_malloc(size)) ?                                     \
+    (((string).start = YAML_MALLOC(size)) ?                                     \
         ((string).pointer = (string).start,                                     \
          (string).end = (string).start+(size),                                  \
          memset((string).start, 0, (size)),                                     \
@@ -419,10 +420,10 @@
 YAML_DECLARE(int)
 yaml_queue_extend(void **start, void **head, void **tail, void **end);
 
-#define STACK_INIT(context,stack,size)                                          \
-    (((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ?             \
+#define STACK_INIT(context,stack,type)                                     \
+  (((stack).start = (type)yaml_malloc(INITIAL_STACK_SIZE*sizeof(*(stack).start))) ? \
         ((stack).top = (stack).start,                                           \
-         (stack).end = (stack).start+(size),                                    \
+         (stack).end = (stack).start+INITIAL_STACK_SIZE,                        \
          1) :                                                                   \
         ((context)->error = YAML_MEMORY_ERROR,                                  \
          0))
@@ -452,8 +453,8 @@
 #define POP(context,stack)                                                      \
     (*(--(stack).top))
 
-#define QUEUE_INIT(context,queue,size)                                          \
-    (((queue).start = yaml_malloc((size)*sizeof(*(queue).start))) ?             \
+#define QUEUE_INIT(context,queue,size,type)                                     \
+  (((queue).start = (type)yaml_malloc((size)*sizeof(*(queue).start))) ?         \
         ((queue).head = (queue).tail = (queue).start,                           \
          (queue).end = (queue).start+(size),                                    \
          1) :                                                                   \
@@ -657,8 +658,33 @@
      (node).data.mapping.pairs.top = (node_pairs_start),                        \
      (node).data.mapping.style = (node_style))
 
+/* Strict C compiler warning helpers */
+
+#if defined(__clang__) || defined(__GNUC__)
+#  define HASATTRIBUTE_UNUSED
+#endif
+#ifdef HASATTRIBUTE_UNUSED
+#  define __attribute__unused__             __attribute__((__unused__))
+#else
+#  define __attribute__unused__
+#endif
+
+/* Shim arguments are arguments that must be included in your function,
+ * but serve no purpose inside.  Silence compiler warnings. */
+#define SHIM(a) /*@unused@*/ a __attribute__unused__
+
+/* UNUSED_PARAM() marks a shim argument in the body to silence compiler warnings */
+#ifdef __clang__
+#  define UNUSED_PARAM(a) (void)(a);
+#else
+#  define UNUSED_PARAM(a) /*@-noeffect*/if (0) (void)(a)/*@=noeffect*/;
+#endif
+
+#define YAML_MALLOC_STATIC(type) (type*)yaml_malloc(sizeof(type))
+#define YAML_MALLOC(size)        (yaml_char_t *)yaml_malloc(size)
+
 /* For Haskell yaml package, since we do not use the configure script */
-#define YAML_VERSION_STRING "0.1.7"
+#define YAML_VERSION_STRING "0.2.1"
 #define YAML_VERSION_MAJOR 0
-#define YAML_VERSION_MINOR 1
-#define YAML_VERSION_PATCH 7
+#define YAML_VERSION_MINOR 2
+#define YAML_VERSION_PATCH 1
diff --git a/test/Data/YamlSpec.hs b/test/Data/YamlSpec.hs
--- a/test/Data/YamlSpec.hs
+++ b/test/Data/YamlSpec.hs
@@ -46,6 +46,11 @@
 
 deriveJSON defaultOptions ''TestJSON
 
+shouldDecode :: (Show a, D.FromJSON a, Eq a) => B8.ByteString -> a -> IO ()
+shouldDecode bs expected = do
+  actual <- D.decodeThrow bs
+  actual `shouldBe` expected
+
 main :: IO ()
 main = hspec spec
 
@@ -120,13 +125,13 @@
     describe "special keys" $ do
         let tester key = it (T.unpack key) $
                 let value = object [key .= True]
-                 in D.decode (D.encode value) `shouldBe` Just value
+                 in D.encode value `shouldDecode` value
         mapM_ tester specialStrings
 
     describe "special values" $ do
         let tester value = it (T.unpack value) $
                 let value' = object ["foo" .= value]
-                 in D.decode (D.encode value') `shouldBe` Just value'
+                 in D.encode value' `shouldDecode` value'
         mapM_ tester specialStrings
 
     describe "decodeFileEither" $ do
@@ -149,13 +154,13 @@
         let special = words "y Y On ON false 12345 12345.0 12345a 12e3"
         forM_ special $ \w -> it w $
             let v = object ["word" .= w]
-             in D.decode (D.encode v) `shouldBe` Just v
+             in D.encode v `shouldDecode` v
         it "no tags" $ D.encode (object ["word" .= ("true" :: String)]) `shouldBe` "word: 'true'\n"
 
     it "aliases in keys #49" caseIssue49
 
     it "serialization of +123 #64" $ do
-        D.decode (D.encode ("+123" :: String)) `shouldBe` Just ("+123" :: String)
+        D.encode ("+123" :: String) `shouldDecode` ("+123" :: String)
 
     it "preserves Scientific precision" casePreservesScientificPrecision
 
@@ -299,9 +304,6 @@
 mappingKey (D.Object m) k = (fromJust . M.lookup (T.pack k) $ m)
 mappingKey _ _ = error "expected Object"
 
-decodeYaml :: String -> Maybe D.Value
-decodeYaml s = D.decode $ B8.pack s
-
 sample :: D.Value
 sample = array
     [ D.String "foo"
@@ -313,20 +315,17 @@
     ]
 
 caseEncodeDecodeData :: Assertion
-caseEncodeDecodeData = do
-    let out = D.decode $ D.encode sample
-    out @?= Just sample
+caseEncodeDecodeData = D.encode sample `shouldDecode` sample
 
 caseEncodeDecodeDataPretty :: Assertion
-caseEncodeDecodeDataPretty = do
-    let out = D.decode $ Pretty.encodePretty Pretty.defConfig sample
-    out @?= Just sample
+caseEncodeDecodeDataPretty =
+    Pretty.encodePretty Pretty.defConfig sample `shouldDecode` sample
 
 caseEncodeDecodeFileData :: Assertion
 caseEncodeDecodeFileData = withFile "" $ \fp -> do
     D.encodeFile fp sample
-    out <- D.decodeFile fp
-    out @?= Just sample
+    out <- D.decodeFileThrow fp
+    out @?= sample
 
 caseEncodeDecodeNonAsciiFileData :: Assertion
 caseEncodeDecodeNonAsciiFileData = do
@@ -334,89 +333,74 @@
   inTempDirectory $ do
     createDirectory "accenté"
     D.encodeFile "accenté/bar.yaml" mySample
-    out1 <- D.decodeFile "accenté/bar.yaml"
-    out1 @?= Just mySample
+    out1 <- D.decodeFileThrow "accenté/bar.yaml"
+    out1 @?= mySample
 
   c <- readFile "test/resources/accent/foo.yaml"
   inTempDirectory $ do
     createDirectoryIfMissing True "test/resources/unicode/accenté/"
     writeFile "test/resources/unicode/accenté/foo.yaml" c
-    out2 <- D.decodeFile "test/resources/unicode/accenté/foo.yaml"
-    out2 @?= Just mySample
+    out2 <- D.decodeFileThrow "test/resources/unicode/accenté/foo.yaml"
+    out2 @?= mySample
 
 caseEncodeDecodeStrings :: Assertion
-caseEncodeDecodeStrings = do
-    let out = D.decode $ D.encode sample
-    out @?= Just sample
+caseEncodeDecodeStrings = D.encode sample `shouldDecode` sample
 
 caseEncodeDecodeStringsPretty :: Assertion
-caseEncodeDecodeStringsPretty = do
-    let out = D.decode $ Pretty.encodePretty Pretty.defConfig sample
-    out @?= Just sample
+caseEncodeDecodeStringsPretty =
+    Pretty.encodePretty Pretty.defConfig sample `shouldDecode` sample
 
 caseDecodeInvalid :: Assertion
-caseDecodeInvalid = do
-    let invalid = B8.pack "\tthis is 'not' valid :-)"
-    Nothing @=? (D.decode invalid :: Maybe D.Value)
+caseDecodeInvalid =
+    D.decodeThrow "\tthis is 'not' valid :-)" `shouldBe`
+    (Nothing :: Maybe D.Value)
 
 caseSimpleScalarAlias :: Assertion
-caseSimpleScalarAlias = do
-    let maybeRes = decodeYaml "- &anch foo\n- baz\n- *anch"
-    isJust maybeRes @? "decoder should return Just YamlObject but returned Nothing"
-    let res = fromJust maybeRes
-    res @?= array [(mkScalar "foo"), (mkScalar "baz"), (mkScalar "foo")]
+caseSimpleScalarAlias =
+    "- &anch foo\n- baz\n- *anch" `shouldDecode`
+    array [(mkScalar "foo"), (mkScalar "baz"), (mkScalar "foo")]
 
 caseSimpleSequenceAlias :: Assertion
-caseSimpleSequenceAlias = do
-    let maybeRes = decodeYaml "seq: &anch\n  - foo\n  - baz\nseq2: *anch"
-    isJust maybeRes @? "decoder should return Just YamlObject but returned Nothing"
-    let res = fromJust maybeRes
-    res @?= object [("seq", array [(mkScalar "foo"), (mkScalar "baz")]), ("seq2", array [(mkScalar "foo"), (mkScalar "baz")])]
+caseSimpleSequenceAlias =
+    "seq: &anch\n  - foo\n  - baz\nseq2: *anch" `shouldDecode`
+    object [("seq", array [(mkScalar "foo"), (mkScalar "baz")]), ("seq2", array [(mkScalar "foo"), (mkScalar "baz")])]
 
 caseSimpleMappingAlias :: Assertion
-caseSimpleMappingAlias = do
-    let maybeRes = decodeYaml "map: &anch\n  key1: foo\n  key2: baz\nmap2: *anch"
-    isJust maybeRes @? "decoder should return Just YamlObject but returned Nothing"
-    let res = fromJust maybeRes
-    res @?= object [(T.pack "map", object [("key1", mkScalar "foo"), ("key2", (mkScalar "baz"))]), (T.pack "map2", object [("key1", (mkScalar "foo")), ("key2", mkScalar "baz")])]
+caseSimpleMappingAlias =
+    "map: &anch\n  key1: foo\n  key2: baz\nmap2: *anch" `shouldDecode`
+    object [(T.pack "map", object [("key1", mkScalar "foo"), ("key2", (mkScalar "baz"))]), (T.pack "map2", object [("key1", (mkScalar "foo")), ("key2", mkScalar "baz")])]
 
 caseMappingAliasBeforeAnchor :: Assertion
-caseMappingAliasBeforeAnchor = do
-    let res = decodeYaml "map: *anch\nmap2: &anch\n  key1: foo\n  key2: baz"
-    isNothing res @? "decode should return Nothing due to unknown alias"
+caseMappingAliasBeforeAnchor =
+    case D.decodeThrow "map: *anch\nmap2: &anch\n  key1: foo\n  key2: baz" of
+      Nothing -> pure ()
+      Just (_ :: D.Value) -> error "decode should return Nothing due to unknown alias"
 
 caseMappingAliasInsideAnchor :: Assertion
 caseMappingAliasInsideAnchor = do
-    let res = decodeYaml "map: &anch\n  key1: foo\n  key2: *anch"
-    isNothing res @? "decode should return Nothing due to unknown alias"
+    case D.decodeThrow "map: &anch\n  key1: foo\n  key2: *anch" of
+      Nothing -> pure ()
+      Just (_ :: D.Value) -> error "decode should return Nothing due to unknown alias"
 
 caseScalarAliasOverriding :: Assertion
-caseScalarAliasOverriding = do
-    let maybeRes = decodeYaml "- &anch foo\n- baz\n- *anch\n- &anch boo\n- buz\n- *anch"
-    isJust maybeRes @? "decoder should return Just YamlObject but returned Nothing"
-    let res = fromJust maybeRes
-    res @?= array [(mkScalar "foo"), (mkScalar "baz"), (mkScalar "foo"), (mkScalar "boo"), (mkScalar "buz"), (mkScalar "boo")]
+caseScalarAliasOverriding =
+    "- &anch foo\n- baz\n- *anch\n- &anch boo\n- buz\n- *anch" `shouldDecode`
+    array [(mkScalar "foo"), (mkScalar "baz"), (mkScalar "foo"), (mkScalar "boo"), (mkScalar "buz"), (mkScalar "boo")]
 
 caseAllKeysShouldBeUnique :: Assertion
 caseAllKeysShouldBeUnique = do
-    let maybeRes = decodeYaml "foo1: foo\nfoo2: baz\nfoo1: buz"
-    isJust maybeRes @? "decoder should return Just YamlObject but returned Nothing"
-    let res = fromJust maybeRes
-    mappingKey res "foo1" @?= (mkScalar "buz")
+    res <- D.decodeThrow "foo1: foo\nfoo2: baz\nfoo1: buz"
+    mappingKey res "foo1" `shouldBe` mkScalar "buz"
 
 caseSimpleMappingMerge :: Assertion
 caseSimpleMappingMerge = do
-    let maybeRes = decodeYaml "foo1: foo\nfoo2: baz\n<<:\n  foo1: buz\n  foo3: fuz"
-    isJust maybeRes @? "decoder should return Just YamlObject but returned Nothing"
-    let res = fromJust maybeRes
-    mappingKey res "foo1" @?= (mkScalar "foo")
-    mappingKey res "foo3" @?= (mkScalar "fuz")
+    res <- D.decodeThrow "foo1: foo\nfoo2: baz\n<<:\n  foo1: buz\n  foo3: fuz"
+    mappingKey res "foo1" `shouldBe` mkScalar "foo"
+    mappingKey res "foo3" `shouldBe` mkScalar "fuz"
 
 caseMergeSequence :: Assertion
 caseMergeSequence = do
-    let maybeRes = decodeYaml "m1: &m1\n  k1: !!str 1\n  k2: !!str 2\nm2: &m2\n  k1: !!str 3\n  k3: !!str 4\nfoo1: foo\n<<: [ *m1, *m2 ]"
-    isJust maybeRes @? "decoder should return Just YamlObject but returned Nothing"
-    let res = fromJust maybeRes
+    res <- D.decodeThrow "m1: &m1\n  k1: !!str 1\n  k2: !!str 2\nm2: &m2\n  k1: !!str 3\n  k3: !!str 4\nfoo1: foo\n<<: [ *m1, *m2 ]"
     mappingKey res "foo1" @?= (mkScalar "foo")
     mappingKey res "k1" @?= (D.String "1")
     mappingKey res "k2" @?= (D.String "2")
@@ -424,7 +408,7 @@
 
 caseDataTypes :: Assertion
 caseDataTypes =
-    D.decode (D.encode val) @?= Just val
+    D.encode val `shouldDecode` val
   where
     val = object
         [ ("string", D.String "foo")
@@ -437,11 +421,11 @@
 
 caseEncodeInvalidNumbers :: Assertion
 caseEncodeInvalidNumbers =
-    D.encode (D.String ".") @?= ".\n"
+    D.encode (D.String ".") `shouldBe` ".\n"
 
 caseDataTypesPretty :: Assertion
 caseDataTypesPretty =
-    D.decode (Pretty.encodePretty Pretty.defConfig val) @?= Just val
+    Pretty.encodePretty Pretty.defConfig val `shouldDecode` val
   where
     val = object
         [ ("string", D.String "foo")
@@ -452,21 +436,21 @@
         , ("null", D.Null)
         ]
 caseQuotedNumber, caseUnquotedNumber, caseAttribNumber, caseIntegerDecimals :: Assertion
-caseQuotedNumber = D.decode "foo: \"1234\"" @?= Just (object [("foo", D.String "1234")])
-caseUnquotedNumber = D.decode "foo: 1234" @?= Just (object [("foo", D.Number 1234)])
-caseAttribNumber = D.decode "foo: !!str 1234" @?= Just (object [("foo", D.String "1234")])
-caseIntegerDecimals = D.encode (1 :: Int) @?= "1\n"
+caseQuotedNumber = "foo: \"1234\"" `shouldDecode` object [("foo", D.String "1234")]
+caseUnquotedNumber = "foo: 1234" `shouldDecode` object [("foo", D.Number 1234)]
+caseAttribNumber = "foo: !!str 1234" `shouldDecode` object [("foo", D.String "1234")]
+caseIntegerDecimals = "1\n" `shouldDecode` (1 :: Int)
 
-obj :: Maybe D.Value
-obj = Just (object [("foo", D.Bool False), ("bar", D.Bool True), ("baz", D.Bool True)])
+obj :: D.Value
+obj = object [("foo", D.Bool False), ("bar", D.Bool True), ("baz", D.Bool True)]
 
 caseLowercaseBool, caseUppercaseBool, caseTitlecaseBool :: Assertion
-caseLowercaseBool = D.decode "foo: off\nbar: y\nbaz: true" @?= obj
-caseUppercaseBool = D.decode "foo: FALSE\nbar: Y\nbaz: ON" @?= obj
-caseTitlecaseBool = D.decode "foo: No\nbar: Yes\nbaz: True" @?= obj
+caseLowercaseBool = "foo: off\nbar: y\nbaz: true" `shouldDecode` obj
+caseUppercaseBool = "foo: FALSE\nbar: Y\nbaz: ON" `shouldDecode` obj
+caseTitlecaseBool = "foo: No\nbar: Yes\nbaz: True" `shouldDecode` obj
 
 caseEmptyInput :: Assertion
-caseEmptyInput = D.decodeEither B8.empty @?= Right D.Null
+caseEmptyInput = B8.empty `shouldDecode` D.Null
 
 caseEmptyInputFile :: Assertion
 caseEmptyInputFile = do
@@ -474,7 +458,7 @@
     either (Left . D.prettyPrintParseException) Right out @?= Right D.Null
 
 caseCommentOnlyInput :: Assertion
-caseCommentOnlyInput = D.decodeEither "# comment\n" @?= Right D.Null
+caseCommentOnlyInput = "# comment\n" `shouldDecode` D.Null
 
 caseCommentOnlyInputFile :: Assertion
 caseCommentOnlyInputFile = do
@@ -483,13 +467,12 @@
 
 checkNull :: T.Text -> Spec
 checkNull x =
-    it ("null recognized: " ++ show x) assertion
-  where
-    assertion = Just (object [("foo", D.Null)]) @=? D.decode (B8.pack $ "foo: " ++ T.unpack x)
+    it ("null recognized: " ++ show x) $
+      B8.pack ("foo: " ++ T.unpack x) `shouldDecode` object [("foo", D.Null)]
 
 caseStripAlias :: Assertion
 caseStripAlias =
-    D.decode src @?= Just (object
+    src `shouldDecode` object
         [ "Default" .= object
             [ "foo" .= (1 :: Int)
             , "bar" .= (2 :: Int)
@@ -499,24 +482,24 @@
             , "bar" .= (2 :: Int)
             , "key" .= (3 :: Int)
             ]
-        ])
+        ]
   where
     src = "Default: &def\n  foo: 1\n  bar: 2\nObj:\n  <<: *def\n  key: 3\n"
 
 caseIssue49 :: Assertion
 caseIssue49 =
-    D.decodeEither src @?= Right (object
+    src `shouldDecode` object
         [ "a" .= object [ "value" .= (1.0 :: Double) ]
         , "b" .= object [ "value" .= (1.2 :: Double) ]
-        ])
+        ]
   where
     src = "---\na:\n  &id5 value: 1.0\nb:\n  *id5: 1.2"
 
 -- | We cannot guarantee this before aeson started using 'Scientific'.
 casePreservesScientificPrecision :: Assertion
 casePreservesScientificPrecision = do
-    D.decodeEither "x: 1e-100000" @?= Right (object
-        [ "x" .= D.Number (read "1e-100000") ])
+    "x: 1e-100000" `shouldDecode` object
+        [ "x" .= D.Number (read "1e-100000") ]
     -- Note that this ought to work also without 'Scientific', given
     -- that @read (show "9.78159610558926e-5") == 9.78159610558926e-5@.
     -- However, it didn't work (and still doesn't work with aeson < 0.7)
@@ -526,8 +509,8 @@
     -- can be;
     -- * Even if we used 'Data.Text.Read.rational' we would not get good
     -- results, because of <https://github.com/bos/text/issues/34>.
-    D.decodeEither "x: 9.78159610558926e-5" @?= Right (object
-        [ "x" .= D.Number (read "9.78159610558926e-5") ])
+    "x: 9.78159610558926e-5" `shouldDecode` object
+        [ "x" .= D.Number (read "9.78159610558926e-5") ]
 
 caseTruncatesFiles :: Assertion
 caseTruncatesFiles = withSystemTempFile "truncate.yaml" $ \fp h -> do
diff --git a/yaml.cabal b/yaml.cabal
--- a/yaml.cabal
+++ b/yaml.cabal
@@ -1,5 +1,5 @@
 name:            yaml
-version:         0.8.30
+version:         0.8.31
 license:         BSD3
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>, Anton Ageev <antage@gmail.com>,Kirill Simonov
@@ -46,7 +46,9 @@
 
 library
     other-extensions: LambdaCase
-    build-depends:   base >= 4 && < 5
+    if impl(ghc < 8.0.2)
+      buildable: False
+    build-depends:   base >= 4.9.1 && < 5
                    , transformers >= 0.1
                    , bytestring >= 0.9.1.4
                    , conduit >= 1.2.8 && < 1.4
