diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -130,23 +130,23 @@
    -- unsetEnvironment (toEnv :: EnvList ConnectInfo)  -- remove when done
 ```
 
-Our parser might also make use a set of an optional default values provided by the user, 
+Our parser might also make use a set of an optional default values provided by the user,
 for dealing with errors when reading from the environment
 
 ```haskell
 instance FromEnv ConnectInfo where
-  fromEnv Nothing = 
+  fromEnv Nothing =
     ConnectInfo <$> envMaybe "PG_HOST" .!= "localhost"
 		<*> env "PG_PORT"
 		<*> env "PG_USER"
 		<*> env "PG_PASS"
 		<*> env "PG_DB"
-        
-  fromEnv (Just def) = 
+
+  fromEnv (Just def) =
     ConnectInfo <$> envMaybe "PG_HOST" .!= (pgHost def)
 		<*> envMaybe "PG_PORT" .!= (pgPort def)
 		<*> env "PG_USER" .!= (pgUser def)
-		<*> env "PG_PASS" .!= (pgPass def) 
+		<*> env "PG_PASS" .!= (pgPass def)
 		<*> env "PG_DB" .!= (pgDB def)
 ```
 
@@ -193,9 +193,9 @@
 defConfig = PGConfig "localhost" 5432
 
 main :: IO ()
-main =
+main = do
   _ <- setEnv "PG_HOST" "customURL" True
-  print =<< decodeWithDefaults defConfig :: IO (Either String PGConfig)
+  print =<< decodeWithDefaults defConfig
  -- > PGConfig { pgHost = "customURL", pgPort = 5432 }
 ```
 
@@ -240,8 +240,8 @@
 import GHC.Generics
 
 data PGConfig = PGConfig {
-    connectHost :: String -- "PG_HOST"
-  , connectPort :: Int    -- "PG_PORT"
+    pgHost :: String -- "PG_HOST"
+  , pgPort :: Int    -- "PG_PORT"
   } deriving (Generic, Show)
 
 -- All fields will be converted to uppercase
diff --git a/envy.cabal b/envy.cabal
--- a/envy.cabal
+++ b/envy.cabal
@@ -1,11 +1,11 @@
 name:                envy
-version:             2.0.0.0
+version:             2.1.5.0
 synopsis:            An environmentally friendly way to deal with environment variables
 license:             BSD3
 license-file:        LICENSE
 author:              David Johnson, Tim Adams, Eric Mertens, Nicolas Rolland
-maintainer:          djohnson.m@gmail.com
-copyright:           David Johnson (c) 2015-2020
+maintainer:          code@dmj.io
+copyright:           David Johnson (c) 2015-2025
 category:            System
 build-type:          Simple
 cabal-version:       >=1.10
@@ -20,13 +20,13 @@
   exposed-modules:      System.Envy
   ghc-options:          -Wall
   hs-source-dirs:       src
-  build-depends:        base         >= 4.7 && < 5
-                      , bytestring   == 0.10.*
-                      , containers   >= 0.5 && < 0.7
-                      , mtl          == 2.2.*
-                      , text         == 1.2.*
+  build-depends:        base         >= 4.11 && < 5
+                      , bytestring   >= 0.10 && < 0.13
+                      , containers   >= 0.5 && < 0.9
+                      , mtl          == 2.2.* || == 2.3.*
+                      , text         == 1.2.* || >= 2.0 && <2.2
                       , time         >= 1.5 && < 2.0
-                      , transformers >= 0.4 && < 0.6
+                      , transformers >= 0.4 && < 0.7
   default-language:     Haskell2010
 
 test-suite spec
diff --git a/examples/Test.hs b/examples/Test.hs
--- a/examples/Test.hs
+++ b/examples/Test.hs
@@ -13,10 +13,10 @@
   defConfig = PGConfig "localhost" 5432
 
 instance FromEnv PGConfig where
-  fromEnv = fromEnvCustom (Option 7 "PG")
+  fromEnv = gFromEnvCustom (Option 7 "PG")
   -- Generically creates instance for retrieving environment variables (PG_HOST, PG_PORT)
 
 main :: IO ()
 main =
-  print =<< decodeEnv :: IO (Either String PGConfig)
+  print =<< (decodeEnv :: IO (Either String PGConfig))
  -- PGConfig { pgHost = "foobah", pgPort = 5432 }
diff --git a/src/System/Envy.hs b/src/System/Envy.hs
--- a/src/System/Envy.hs
+++ b/src/System/Envy.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE DeriveGeneric              #-}
 {-# LANGUAGE RecordWildCards            #-}
+{-# LANGUAGE StandaloneDeriving         #-}
 {-# LANGUAGE TypeOperators              #-}
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE MultiParamTypeClasses      #-}
@@ -15,7 +15,7 @@
 -- |
 -- Module      : System.Envy
 -- Copyright   : (c) David Johnson 2015
--- Maintainer  : djohnson.m@gmail.com
+-- Maintainer  : code@dmj.io
 -- Stability   : experimental
 -- Portability : POSIX
 --
@@ -48,6 +48,7 @@
 module System.Envy
        ( -- * Classes
          FromEnv (..)
+       , GFromEnv (..)
        , ToEnv   (..)
        , Var     (..)
        , EnvList (..)
@@ -67,6 +68,8 @@
        , envMaybe
        , (.=)
        , (.!=)
+         -- * Utility Types
+       , ReadShowVar (..)
          -- * Generics
        , DefConfig (..)
        , Option (..)
@@ -76,11 +79,16 @@
        ) where
 ------------------------------------------------------------------------------
 import           Control.Applicative
-import           Control.Monad.Except
+import           Control.Monad (MonadPlus)
+import           Control.Monad.Except (ExceptT, MonadError, runExceptT, throwError)
+import           Control.Monad.IO.Class (MonadIO, liftIO)
 import           Control.Exception
+import           Data.Functor.Identity
 import           Data.Maybe
+import           Data.Monoid
 import           Data.Char
 import           Data.Time
+import           Data.Kind
 import           GHC.Generics
 import           Data.Typeable
 import           System.Environment.Blank
@@ -98,6 +106,9 @@
   deriving ( Functor, Monad, Applicative, MonadError String
            , MonadIO, Alternative, MonadPlus )
 
+instance MonadFail Parser where
+  fail = Parser . throwError
+
 ------------------------------------------------------------------------------
 -- | Variable type, smart constructor for handling environment variables.
 data EnvVar = EnvVar {
@@ -256,7 +267,7 @@
       snake :: String -> String
       snake = map toUpper . snakeCase
 
-data SelectorProxy (s :: Meta) (f :: * -> *) a = SelectorProxy
+data SelectorProxy (s :: Meta) (f :: Type -> Type) a = SelectorProxy
 
 ------------------------------------------------------------------------------
 -- | Type class for objects which can be converted to a set of
@@ -311,6 +322,19 @@
   fromVar  s = Just <$> fromVar s
 
 ------------------------------------------------------------------------------
+deriving instance (Var a, Typeable a) => Var (Last a)
+deriving instance (Var a, Typeable a) => Var (First a)
+deriving instance (Var a, Typeable a) => Var (Identity a)
+
+------------------------------------------------------------------------------
+-- | A utility type to use any instance of 'Read' and 'Show' as an instance of
+--   'Var'.
+newtype ReadShowVar a = ReadShowVar { unReadShowVar :: a }
+
+instance (Typeable a, Show a, Read a) => Var (ReadShowVar a) where
+  toVar = show . unReadShowVar
+  fromVar = fmap ReadShowVar . readMaybe
+------------------------------------------------------------------------------
 -- | Environment retrieval with failure info
 decodeEnv :: FromEnv a => IO (Either String a)
 decodeEnv = evalParser (fromEnv Nothing)
@@ -326,7 +350,7 @@
 ------------------------------------------------------------------------------
 -- | Environment retrieval with default values provided
 decodeWithDefaults :: FromEnv a => a -> IO a
-decodeWithDefaults def = (\(Right x) -> x) <$> evalParser (fromEnv (Just def))
+decodeWithDefaults def = either error pure =<< evalParser (fromEnv (Just def))
 
 ------------------------------------------------------------------------------
 -- | Catch an IO exception and return it in an Either.
