diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+![logo](supply_monad.png)
+
+[![Language](https://img.shields.io/badge/language-Haskell-yellow.svg)](https://www.haskell.org/) [![Hackage](https://img.shields.io/hackage/v/monad-supply.svg)](http://hackage.haskell.org/package/monad-supply)
+
+> A monad to support computations which consume values from a (possibly infinite) supply.
+
+## Disclaimer
+
+Please let me know if there is any issue with the licensing or copyright — I am assuming that, because the code appears on the HaskellWiki pages, it follows the [Simple license](https://wiki.haskell.org/HaskellWiki:Copyrights) found there, and that packaging it in this way is not a problem.
+
+## About this library
+
+I pulled this more or less verbatim from the HaskellWiki, since I wanted it on 
+Hackage for distribution purposes:
+
+  http://www.haskell.org/haskellwiki/New_monads/MonadSupply
+
+Some stuff was added, like a monoid instance and various helper functions.
+
+    This library is based on code found on the HaskellWiki, and subject to the
+    license found there:
+
+      http://www.haskell.org/haskellwiki/HaskellWiki:Copyrights
+
+    Permission is hereby granted, free of charge, to any person obtaining this
+    work (the "Work"), to deal in the Work without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Work, and to permit
+    persons to whom the Work is furnished to do so.
+
+    THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS IN
+    THE WORK.
diff --git a/monad-supply.cabal b/monad-supply.cabal
--- a/monad-supply.cabal
+++ b/monad-supply.cabal
@@ -1,23 +1,42 @@
-Name:          monad-supply
-Build-type:    Simple
-Version:       0.6
-Cabal-Version: >= 1.6
-Synopsis:      Stateful supply monad.
-Description:   Support for computations which consume values from a (possibly infinite) supply.
-License:       OtherLicense
-License-file:  LICENSE
-Category:      Control, Data, Monads
-Author:        Geoff Hulette and unknown HaskellWiki contributor(s).
-Maintainer:    Geoff Hulette <ghulette@gmail.com>
-Stability:     experimental
-Tested-With:   GHC == 7.0.3
+cabal-version: 1.12
 
-Library
-  Exposed-modules: Control.Monad.Supply
-  Hs-Source-Dirs:  src
-  Build-Depends:   base >= 4 && < 5,mtl >= 2
-  GHC-Options:     -Wall
+-- This file has been generated from package.yaml by hpack version 0.33.0.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 39c53de256cb793f3b30bbe8f4c1d4e6bc458746ac18bbbb788ecb6cf7b7a265
 
-Source-Repository head
-  type:     git
-  location: git://github.com/ghulette/monad-supply.git
+name:           monad-supply
+version:        0.9
+synopsis:       Stateful supply monad
+description:    Support for computations which consume values from a (possibly infinite) supply.
+category:       Control, Data, Monad
+stability:      experimental
+homepage:       https://github.com/ghulette/monad-supply
+bug-reports:    https://github.com/ghulette/monad-supply/issues
+author:         Geoff Hulette and HaskellWiki contributors
+maintainer:     Geoff Hulette <geoff@hulette.net>
+copyright:      2011-2020 Geoff Hulette and HaskellWiki contributors
+license:        OtherLicense
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+
+source-repository head
+  type: git
+  location: https://github.com/ghulette/monad-supply
+
+library
+  exposed-modules:
+      Control.Monad.Supply
+  other-modules:
+      Paths_monad_supply
+  hs-source-dirs:
+      src
+  ghc-options: -Wall
+  build-depends:
+      base >=4.7 && <5
+    , mtl >=2.2.2 && <3.0.0
+    , transformers >=0.5.6.2 && <0.6.0.0
+  default-language: Haskell2010
diff --git a/src/Control/Monad/Supply.hs b/src/Control/Monad/Supply.hs
--- a/src/Control/Monad/Supply.hs
+++ b/src/Control/Monad/Supply.hs
@@ -1,82 +1,100 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FunctionalDependencies #-}
-{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE FunctionalDependencies     #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances       #-}
 
 -- | Support for computations which consume values from a (possibly infinite)
 -- supply. See <http://www.haskell.org/haskellwiki/New_monads/MonadSupply> for
 -- details.
+
 module Control.Monad.Supply
-( MonadSupply (..)
-, SupplyT
-, Supply
-, evalSupplyT
-, evalSupply
-, runSupplyT
-, runSupply
-, supplies
-) where
+    ( MonadSupply(..)
+    , SupplyT
+    , Supply
+    , evalSupplyT
+    , evalSupply
+    , runSupplyT
+    , runSupply
+    , supplies
+    ) where
 
-import Control.Applicative
-import Control.Monad.Identity
-import Control.Monad.State
-import Control.Monad.Error
-import Control.Monad.Reader
-import Control.Monad.Writer
+import           Control.Monad             (replicateM)
+import           Control.Monad.Except      (ExceptT, MonadError, throwError, catchError)
+import           Control.Monad.Fix         (MonadFix)
+import           Control.Monad.IO.Class    (MonadIO)
+import           Control.Monad.Reader      (ReaderT)
+import           Control.Monad.State       (StateT, get, gets, put, evalStateT, runStateT)
+import           Control.Monad.Trans       (MonadTrans, lift)
+import           Control.Monad.Trans.Maybe (MaybeT)
+import           Control.Monad.Writer      (WriterT)
+#if !MIN_VERSION_base(4,11,0)
+import           Control.Monad.Fail        (MonadFail)
+import           Data.Semigroup            (Semigroup, (<>))
+#endif
 
+import qualified Control.Monad.Trans.State.Lazy as LazyState
+
+
 class Monad m => MonadSupply s m | m -> s where
-  supply :: m s
-  peek :: m s
-  exhausted :: m Bool
+    supply :: m s
+    peek :: m s
+    exhausted :: m Bool
 
 -- | Supply monad transformer.
-newtype SupplyT s m a = SupplyT (StateT [s] m a)
-  deriving (Functor, Applicative, Monad, MonadTrans, MonadIO, MonadFix)
+newtype SupplyT s m a = SupplyT { unSupplyT :: StateT [s] m a }
+    deriving (Functor, Applicative, Monad, MonadTrans, MonadIO, MonadFix)
 
--- | Supply monad. 
-newtype Supply s a = Supply (SupplyT s Identity a)
-  deriving (Functor, Applicative, Monad, MonadSupply s, MonadFix)
+instance MonadError e m => MonadError e (SupplyT s m) where
+    throwError = lift . throwError
+    catchError m h =
+        SupplyT $ LazyState.liftCatch catchError (unSupplyT m) (unSupplyT . h)
 
-instance Monad m => MonadSupply s (SupplyT s m) where
-  supply = SupplyT $ do (x:xs) <- get
-                        put xs
-                        return x
-  peek = SupplyT $ gets head
-  exhausted = SupplyT $ gets null
+-- | Supply monad.
+newtype Supply s a = Supply (SupplyT s Maybe a)
+    deriving (Functor, Applicative, Monad, MonadSupply s, MonadFix)
 
+instance MonadFail m => MonadSupply s (SupplyT s m) where
+    supply = SupplyT $ do
+        (x:xs) <- get
+        put xs
+        return x
+    peek = SupplyT $ gets head
+    exhausted = SupplyT $ gets null
+
 -- Monad transformer instances
-instance (Error e,MonadSupply s m) => MonadSupply s (ErrorT e m) where
-  supply = lift supply
-  peek = lift peek
-  exhausted = lift exhausted
+instance (MonadSupply s m) => MonadSupply s (ExceptT e m) where
+    supply = lift supply
+    peek = lift peek
+    exhausted = lift exhausted
 
 instance MonadSupply s m => MonadSupply s (StateT st m) where
-  supply = lift supply
-  peek = lift peek
-  exhausted = lift exhausted
+    supply = lift supply
+    peek = lift peek
+    exhausted = lift exhausted
 
 instance MonadSupply s m => MonadSupply s (ReaderT r m) where
-  supply = lift supply
-  peek = lift peek
-  exhausted = lift exhausted
+    supply = lift supply
+    peek = lift peek
+    exhausted = lift exhausted
 
+instance MonadSupply s m => MonadSupply s (MaybeT m) where
+    supply = lift supply
+    peek = lift peek
+    exhausted = lift exhausted
+
 instance (Monoid w, MonadSupply s m) => MonadSupply s (WriterT w m) where
-  supply = lift supply
-  peek = lift peek
-  exhausted = lift exhausted
+    supply = lift supply
+    peek = lift peek
+    exhausted = lift exhausted
 
--- | Monoid instance for the supply monad. Actually any monad/monoid pair
--- gives rise to this monoid instance, but we can't write its type like that
--- because it would conflict with existing instances provided by Data.Monoid.
---instance (Monoid a, Monad m) => Monoid (m a) where
-instance (Monoid a) => Monoid (Supply s a) where
-  mempty = return mempty
-  m1 `mappend` m2 = do
-    x1 <- m1
-    x2 <- m2
-    return (x1 `mappend` x2)
+instance Semigroup a => Semigroup (Supply s a) where
+    m1 <> m2 = (<>) <$> m1 <*> m2
 
+instance (Semigroup a, Monoid a) => Monoid (Supply s a) where
+    mempty = return mempty
+    m1 `mappend` m2 = m1 <> m2
+
 -- | Get n supplies.
 supplies :: MonadSupply s m => Int -> m [s]
 supplies n = replicateM n supply
@@ -84,11 +102,11 @@
 evalSupplyT :: Monad m => SupplyT s m a -> [s] -> m a
 evalSupplyT (SupplyT s) = evalStateT s
 
-evalSupply :: Supply s a -> [s] -> a
-evalSupply (Supply s) = runIdentity . evalSupplyT s
+evalSupply :: Supply s a -> [s] -> Maybe a
+evalSupply (Supply s) = evalSupplyT s
 
 runSupplyT :: Monad m => SupplyT s m a -> [s] -> m (a,[s])
 runSupplyT (SupplyT s) = runStateT s
 
-runSupply :: Supply s a -> [s] -> (a,[s])
-runSupply (Supply s) = runIdentity . runSupplyT s
+runSupply :: Supply s a -> [s] -> Maybe (a,[s])
+runSupply (Supply s) = runSupplyT s
