diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014-2016, Stephen Diehl
+Copyright (c) 2016, Stephen Diehl
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to
diff --git a/protolude.cabal b/protolude.cabal
--- a/protolude.cabal
+++ b/protolude.cabal
@@ -1,5 +1,5 @@
 name:                protolude
-version:             0.1.0
+version:             0.1.1
 synopsis:            A sensible set of defaults for writing custom Preludes.
 description:         A sensible set of defaults for writing custom Preludes.
 homepage:            https://github.com/sdiehl/protolude
@@ -12,8 +12,15 @@
 build-type:          Simple
 cabal-version:       >=1.10
 tested-with:         
+  GHC == 7.6.1,
+  GHC == 7.6.2,
   GHC == 7.6.3,
-  GHC == 7.8.0
+  GHC == 7.8.1,
+  GHC == 7.8.2,
+  GHC == 7.8.3,
+  GHC == 7.8.4,
+  GHC == 7.10.1,
+  GHC == 7.10.2,
   GHC == 7.10.3
 Bug-Reports:         https://github.com/sdiehl/protolude/issues
 
@@ -33,7 +40,11 @@
     Debug
     List
     Monad
+    Show
     Unsafe
+    Either
+    Functor
+    Bifunctor
 
   default-extensions:
     NoImplicitPrelude
@@ -51,6 +62,7 @@
     mtl              >= 2.1 && <2.3,
     transformers     >= 0.4 && < 0.6,
     text             >= 1.2 && <1.3,
+    stm              >= 2.4 && <2.5,
     string-conv      >= 0.1 && <0.2,
     bytestring       >= 0.10 && <0.11
 
diff --git a/src/Applicative.hs b/src/Applicative.hs
--- a/src/Applicative.hs
+++ b/src/Applicative.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
 module Applicative (
   orAlt,
   orEmpty,
diff --git a/src/Bifunctor.hs b/src/Bifunctor.hs
new file mode 100644
--- /dev/null
+++ b/src/Bifunctor.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Bifunctor (
+  Bifunctor(..)
+) where
+
+import Data.Function (id, (.))
+import Data.Either (Either(..))
+import Control.Applicative ( Const(..) )
+
+class Bifunctor p where
+    {-# MINIMAL bimap | first, second #-}
+
+    bimap :: (a -> b) -> (c -> d) -> p a c -> p b d
+    bimap f g = first f . second g
+
+    first :: (a -> b) -> p a c -> p b c
+    first f = bimap f id
+
+    second :: (b -> c) -> p a b -> p a c
+    second = bimap id
+
+instance Bifunctor (,) where
+    bimap f g ~(a, b) = (f a, g b)
+
+instance Bifunctor ((,,) x1) where
+    bimap f g ~(x1, a, b) = (x1, f a, g b)
+
+instance Bifunctor ((,,,) x1 x2) where
+    bimap f g ~(x1, x2, a, b) = (x1, x2, f a, g b)
+
+instance Bifunctor ((,,,,) x1 x2 x3) where
+    bimap f g ~(x1, x2, x3, a, b) = (x1, x2, x3, f a, g b)
+
+instance Bifunctor ((,,,,,) x1 x2 x3 x4) where
+    bimap f g ~(x1, x2, x3, x4, a, b) = (x1, x2, x3, x4, f a, g b)
+
+instance Bifunctor ((,,,,,,) x1 x2 x3 x4 x5) where
+    bimap f g ~(x1, x2, x3, x4, x5, a, b) = (x1, x2, x3, x4, x5, f a, g b)
+
+instance Bifunctor Either where
+    bimap f _ (Left a) = Left (f a)
+    bimap _ g (Right b) = Right (g b)
+
+instance Bifunctor Const where
+    bimap f _ (Const a) = Const (f a)
diff --git a/src/Bool.hs b/src/Bool.hs
--- a/src/Bool.hs
+++ b/src/Bool.hs
@@ -1,13 +1,17 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
 module Bool (
-    whenM
-  , unlessM
-  , ifM
-  , guardM
-  , bool
-  ) where
+  whenM
+, unlessM
+, ifM
+, guardM
+, bool
+) where
 
-import Prelude
-import Control.Monad (MonadPlus, when, unless, guard)
+import Data.Bool (Bool)
+import Data.Function (flip)
+import Control.Monad (Monad, MonadPlus, when, unless, guard, (>>=), (=<<))
 
 bool :: a -> a -> Bool -> a
 bool f t p = if p then t else f
diff --git a/src/Debug.hs b/src/Debug.hs
--- a/src/Debug.hs
+++ b/src/Debug.hs
@@ -1,15 +1,16 @@
+{-# LANGUAGE Unsafe #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 
 module Debug (
-    undefined
-  , error
-  , trace
-  , traceM
-  , traceIO
-  , traceShow
-  , traceShowM
-  , notImplemented
-  ) where
+  undefined,
+  error,
+  trace,
+  traceM,
+  traceIO,
+  traceShow,
+  traceShowM,
+  notImplemented,
+) where
 
 import qualified Prelude as P
 import qualified Debug.Trace as T
@@ -32,11 +33,11 @@
 
 {-# WARNING traceShowM "'traceShowM' remains in code" #-}
 traceShowM :: (P.Show a, P.Monad m) => a -> m ()
-traceShowM a = T.traceM (P.show a)
+traceShowM a = traceM (P.show a)
 
 {-# WARNING traceM "'traceM' remains in code" #-}
-traceM :: P.Monad m => P.String -> m ()
-traceM = T.traceM
+traceM :: (P.Monad m) => P.String -> m ()
+traceM s = T.trace s (P.return ())
 
 {-# WARNING traceIO "'traceIO' remains in code" #-}
 traceIO :: P.String -> P.IO ()
diff --git a/src/Either.hs b/src/Either.hs
new file mode 100644
--- /dev/null
+++ b/src/Either.hs
@@ -0,0 +1,30 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Either (
+  maybeToLeft
+, maybeToRight
+, leftToMaybe
+, rightToMaybe
+, maybeToEither
+) where
+
+import Data.Function (const)
+import Data.Monoid (Monoid, mempty)
+import Data.Maybe (Maybe(..), maybe)
+import Data.Either (Either(..), either)
+
+leftToMaybe :: Either l r -> Maybe l
+leftToMaybe = either Just (const Nothing)
+
+rightToMaybe :: Either l r -> Maybe r
+rightToMaybe = either (const Nothing) Just
+
+maybeToRight :: l -> Maybe r -> Either l r
+maybeToRight l = maybe (Left l) Right
+
+maybeToLeft :: r -> Maybe l -> Either l r
+maybeToLeft r = maybe (Right r) Left
+
+maybeToEither :: Monoid b => (a -> b) -> Maybe a -> b
+maybeToEither = maybe mempty
diff --git a/src/Functor.hs b/src/Functor.hs
new file mode 100644
--- /dev/null
+++ b/src/Functor.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Functor (
+  Functor(..),
+  ($>),
+  (<$>),
+  void,
+) where
+
+#if (__GLASGOW_HASKELL__ >= 710)
+import Data.Functor (
+    Functor(..)
+  , ($>)
+  , (<$>)
+  , void
+  )
+#else
+import Data.Functor (
+    Functor(..)
+  , (<$>)
+  )
+
+import Data.Function (flip)
+
+infixl 4 $>
+
+($>) :: Functor f => f a -> b -> f b
+($>) = flip (<$)
+
+void :: Functor f => f a -> f ()
+void x = () <$ x
+#endif
diff --git a/src/List.hs b/src/List.hs
--- a/src/List.hs
+++ b/src/List.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
 module List (
   head,
   ordNub,
diff --git a/src/Monad.hs b/src/Monad.hs
--- a/src/Monad.hs
+++ b/src/Monad.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE Safe #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 
 module Monad (
@@ -37,8 +39,14 @@
   , (<$!>)
   ) where
 
-import Prelude (concat, seq)
+import Data.List (concat)
+import Prelude (seq)
+
+#if (__GLASGOW_HASKELL__ >= 710)
+import Control.Monad hiding ((<$!>))
+#else
 import Control.Monad
+#endif
 
 concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b]
 concatMapM f xs = liftM concat (mapM f xs)
@@ -54,3 +62,10 @@
   let z = f x y
   z `seq` return z
 {-# INLINE liftM2' #-}
+
+(<$!>) :: Monad m => (a -> b) -> m a -> m b
+f <$!> m = do
+  x <- m
+  let z = f x
+  z `seq` return z
+{-# INLINE (<$!>) #-}
diff --git a/src/Protolude.hs b/src/Protolude.hs
--- a/src/Protolude.hs
+++ b/src/Protolude.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
 
 module Protolude (
@@ -5,6 +7,7 @@
   identity,
   bool,
   (&),
+  ($!),
   uncons,
   applyN,
   print,
@@ -20,13 +23,28 @@
 import qualified Bool as X
 import qualified Debug as X
 import qualified Monad as X
+import qualified Functor as X
+import qualified Either as X
 import qualified Applicative as X
 
 -- Maybe'ized version of partial functions
 import Safe as X (
     headMay
+  , headDef
   , initMay
+  , initDef
+  , initSafe
   , tailMay
+  , tailDef
+  , tailSafe
+  , lastDef
+  , lastMay
+  , lookupJust
+  , findJust
+  , foldr1May
+  , foldl1May
+  , atMay
+  , atDef
   )
 
 -- Applicatives
@@ -50,20 +68,16 @@
 import Data.Foldable as X hiding (
     foldr1
   , foldl1
-  , maximum
-  , maximumBy
-  , minimum
-  , minimumBy
   )
 import Data.Semiring as X
 import Data.Functor.Identity as X
-import Data.Functor as X (
-    Functor(..)
-  , ($>)
-  , (<$>)
-  , void
-  )
 
+#if (__GLASGOW_HASKELL__ >= 710)
+import Data.Bifunctor as X (Bifunctor(..))
+#else
+import Bifunctor as X (Bifunctor(..))
+#endif
+
 -- Deepseq
 import Control.DeepSeq as X (
     NFData(..)
@@ -74,6 +88,7 @@
 
 -- Data structures
 import Data.Tuple as X
+import Data.Semiring as X
 import Data.List as X (
     splitAt
   , break
@@ -83,6 +98,7 @@
   , filter
   , reverse
   , replicate
+  , take
   )
 import Data.Map as X (Map)
 import Data.Set as X (Set)
@@ -144,9 +160,9 @@
 import Data.Complex as X
 
 import Data.Function as X (
-    id
-  , const
+    const
   , (.)
+  , ($)
   , flip
   , fix
   , on
@@ -155,6 +171,7 @@
 -- Base GHC types
 import GHC.IO as X (IO)
 import GHC.Num as X
+import GHC.Enum as X
 import GHC.Real as X
 import GHC.Float as X
 import GHC.Show as X
@@ -164,6 +181,11 @@
   , FunPtr
   , the
   )
+import GHC.Base as X (
+    (++)
+  , seq
+  , asTypeOf
+  )
 
 -- Genericss
 import GHC.Generics (
@@ -178,12 +200,9 @@
   , S1
   , (:+:)
   , (:*:)
-  , NoSelector
   , Rec0
-  , Par0
   , Constructor(..)
   , Selector(..)
-  , Arity(..)
   , Fixity(..)
   )
 
@@ -229,10 +248,10 @@
 
 -- Concurrency and Parallelism
 import Control.Exception as X
+import Control.Monad.STM as X
 import Control.Concurrent as X
 import Control.Concurrent.Async as X
 
-
 import Foreign.Storable as Exports (Storable)
 
 -- Read instances hiding unsafe builtins (read)
@@ -252,6 +271,11 @@
 (&) :: a -> (a -> b) -> b
 x & f = f x
 
+infixr 0 $!
+
+($!) :: (a -> b) -> a -> b
+($!) = (P.$!)
+
 bool :: a -> a -> Bool -> a
 bool f t b = if b then t else f
 
@@ -263,7 +287,7 @@
 uncons (x:xs) = Just (x, xs)
 
 applyN :: Int -> (a -> a) -> a -> a
-applyN n f = X.foldr (.) id (X.replicate n f)
+applyN n f = X.foldr (.) identity (X.replicate n f)
 
 print :: (X.MonadIO m, P.Show a) => a -> m ()
 print = liftIO . P.print
diff --git a/src/Show.hs b/src/Show.hs
new file mode 100644
--- /dev/null
+++ b/src/Show.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+
+module Show (
+  Print(..),
+  putText,
+  putLText,
+) where
+
+import Prelude ((.), Char, IO)
+import qualified Prelude
+
+import Control.Monad.IO.Class (MonadIO, liftIO)
+import qualified Data.ByteString.Char8 as BS
+import qualified Data.ByteString.Lazy.Char8 as BL
+
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+
+import qualified Data.Text.Lazy as TL
+import qualified Data.Text.Lazy.IO as TL
+
+class Print a where
+  putStr :: MonadIO m => a -> m ()
+  putStrLn :: MonadIO m => a -> m ()
+
+instance Print T.Text where
+  putStr = liftIO . T.putStr
+  putStrLn = liftIO . T.putStrLn
+
+instance Print TL.Text where
+  putStr = liftIO . TL.putStr
+  putStrLn = liftIO . TL.putStrLn
+
+instance Print BS.ByteString where
+  putStr = liftIO . BS.putStr
+  putStrLn = liftIO . BS.putStrLn
+
+instance Print BL.ByteString where
+  putStr = liftIO . BL.putStr
+  putStrLn = liftIO . BL.putStrLn
+
+instance Print [Char] where
+  putStr = liftIO . Prelude.putStr
+  putStrLn = liftIO . Prelude.putStrLn
+
+-- For forcing type inference
+putText :: MonadIO m => T.Text -> m ()
+putText = putStrLn
+{-# SPECIALIZE putText :: T.Text -> IO () #-}
+
+putLText :: MonadIO m => TL.Text -> m ()
+putLText = putStrLn
+{-# SPECIALIZE putLText :: TL.Text -> IO () #-}
