diff --git a/CHANGES.md b/CHANGES.md
deleted file mode 100644
--- a/CHANGES.md
+++ /dev/null
@@ -1,98 +0,0 @@
-0.2.4
-=====
-
-* GHC 8.8.1 support
-
-0.2.3
-=====
-
-* GHC 8.6.1 support
-* Expose `fromLeft` and `fromRight`.
-* Mask `always` and `alwaysSucceeds` from STM export for stm-2.5.
-
-0.2.2
-=====
-
-* Add explicit `witness` function for use as type witness without warnings.
-  Makes undefined semantically distinguishable from type witnesses.
-* Backwards compatible `Protolude.Safe` module for explicit handling of partial
-  list operations.
-* Export `minimumDef`, `maximumDef`.
-* Looser lower-bound on Data.Kind export for GHC 8.0.x.
-
-0.2.1
-====
-
-* Exposes `throwE` and `catchE`.
-* Add `transformers-compat` for old versions of transformers that require
-  `throwE`, `catchE`.
-* Fix `safe` version bounds for new versions.
-* Add `mapExceptT and `withExceptT`.
-* Export `scanl'` and provide shim for backwards compatibility.
-* Add `putErrLn`.
-* Expose `RealFloat`.
-* Expose `GHC.Records` exports for GHC 8.2 and above.
-
-0.2
-====
-
-* Expose `Symbol` and `Nat` types from `GHC.TypeLits` by default.
-* Switch exported `(<>)` to be from `Data.Monoid` instead of Semigroup.
-* Expose `putByteString` and `putLByteString` monomorphic versions of `putStrLn` functions
-* Export `genericLength` and other generic list return functions.
-* Rename `msg` to `fatalErrorMessage`.
-* Export `ExceptT`, `ReaderT`, and `StateT` constructors.
-* Mask `displayException` from default exports.
-* Mask `stToIO` from default exports.
-* Export `NonEmpty` type and constructor for Base 4.9 only.
-* Export `Data.Semigroup` type and functions for Base 4.9 only.
-* Restrict exported symbols from ``async`` to set available in 2.0.
-* Add `(&&^)`, `(||^)`, `(<&&>)`, `(<||>)`
-* Expose `unzip`.
-* Export `maximumMay` and `minimumMay`.
-* Mask `Type` export from `Data.Kind`.
-* Wrap `die` to take `Text` argument instead of `[Char]`.
-* Export constructors `GHC.Generics`: `(:+:)`, `(:*:)`, and `(:.:)`.
-* Expose `StablePtr`, `IntPtr` and `WordPtr` types.
-
-0.1.9
-====
-
-* Make `sum` and `product` strict
-
-0.1.8
-=====
-
-* ``foreach`` for applicative traversals.
-* ``hush`` function for error handling.
-* ``tryIO`` function for error handling.
-* ``pass`` function for noop applicative branches.
-* Mask ``Handler`` typeclass export.
-* Mask ``yield`` function export.
-
-0.1.7
-=====
-
-* Exports monadic ``(>>)`` operator by default.
-* Adds ``traceId`` and ``traceShowId`` functions.
-* Exports``reader`` and ``state``  functions by default.
-* Export lifted ``throwIO`` and ``throwTo`` functions.
-
-0.1.6
-=====
-
-* Adds uncatchable panic exception throwing using Text message.
-* Removes ``printf``
-* Removes ``string-conv`` dependency so Stack build works without ``extra-deps``.
-* Brings ``Callstack`` machinery in for GHC 8.x.
-* Removes ``throw`` and ``assert`` from ``Control.Exception`` exports.
-* Removes ``unsafeShiftL`` and ``unsafeShiftR`` from ``Data.Bits`` exports.
-* Reexport ``throw`` as ``unsafeThrow`` via Unsafe module.
-* Hides all Show class functions. Only the Class itself is exported. Forbids custom instances that are not GHC derived.
-* Export`` encodeUtf8`` and ``decodeUtf8`` functions by default.
-* Adds ``unsnoc`` function.
-
-0.1.5
-=====
-
-* Initial release.
diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,128 @@
+0.3.0
+=====
+
+* GHC 8.10.1 support
+* Use `Protolude.ConvertText` as the default string conversion class. This
+  removes partial functions when converting to/from ByteStrings.
+* Provide `Protolude.Conv` as a compatibility layer for old string conversion
+  interface.
+* Migrated `Debug` and `Unsafe` to `Protolude.Debug` and `Protolude.Unsafe`.
+* Export Unicode functions:
+  - `intToDigit`
+  - `isAlpha`
+  - `isAlphaNum`
+  - `isAscii`
+  - `isControl`
+  - `isDigit`
+  - `isHexDigit`
+  - `isLetter`
+  - `isLower`
+  - `isPrint`
+  - `isSpace`
+  - `isUpper`
+* Export `MonadFail` class.
+* Export `gcast` from Data.Typeable.
+* Export `typeOf` from Data.Typeable.
+* Export `Handler` from Control.Exception.
+* Export `yield` from Control.Concurrency.
+* Provide compatibility module `Protolude.Partial` as single export for unsafe
+  partial functions with the same naming conventions as Prelude.
+
+0.2.4
+=====
+
+* GHC 8.8.1 support
+
+0.2.3
+=====
+
+* GHC 8.6.1 support
+* Export `fromLeft` and `fromRight`.
+* Mask `always` and `alwaysSucceeds` from STM export for stm-2.5.
+
+0.2.2
+=====
+
+* Add explicit `witness` function for use as type witness without warnings.
+  Makes undefined semantically distinguishable from type witnesses.
+* Backwards compatible `Protolude.Safe` module for explicit handling of partial
+  list operations.
+* Export `minimumDef`, `maximumDef`.
+* Looser lower-bound on Data.Kind export for GHC 8.0.x.
+
+0.2.1
+====
+
+* Exposes `throwE` and `catchE`.
+* Add `transformers-compat` for old versions of transformers that require
+  `throwE`, `catchE`.
+* Fix `safe` version bounds for new versions.
+* Add `mapExceptT and `withExceptT`.
+* Export `scanl'` and provide shim for backwards compatibility.
+* Add `putErrLn`.
+* Expose `RealFloat`.
+* Expose `GHC.Records` exports for GHC 8.2 and above.
+
+0.2
+====
+
+* Expose `Symbol` and `Nat` types from `GHC.TypeLits` by default.
+* Switch exported `(<>)` to be from `Data.Monoid` instead of Semigroup.
+* Expose `putByteString` and `putLByteString` monomorphic versions of `putStrLn` functions
+* Export `genericLength` and other generic list return functions.
+* Rename `msg` to `fatalErrorMessage`.
+* Export `ExceptT`, `ReaderT`, and `StateT` constructors.
+* Mask `displayException` from default exports.
+* Mask `stToIO` from default exports.
+* Export `NonEmpty` type and constructor for Base 4.9 only.
+* Export `Data.Semigroup` type and functions for Base 4.9 only.
+* Restrict exported symbols from ``async`` to set available in 2.0.
+* Add `(&&^)`, `(||^)`, `(<&&>)`, `(<||>)`
+* Expose `unzip`.
+* Export `maximumMay` and `minimumMay`.
+* Mask `Type` export from `Data.Kind`.
+* Wrap `die` to take `Text` argument instead of `[Char]`.
+* Export constructors `GHC.Generics`: `(:+:)`, `(:*:)`, and `(:.:)`.
+* Expose `StablePtr`, `IntPtr` and `WordPtr` types.
+
+0.1.9
+====
+
+* Make `sum` and `product` strict
+
+0.1.8
+=====
+
+* ``foreach`` for applicative traversals.
+* ``hush`` function for error handling.
+* ``tryIO`` function for error handling.
+* ``pass`` function for noop applicative branches.
+* Mask ``Handler`` typeclass export.
+* Mask ``yield`` function export.
+
+0.1.7
+=====
+
+* Exports monadic ``(>>)`` operator by default.
+* Adds ``traceId`` and ``traceShowId`` functions.
+* Exports``reader`` and ``state``  functions by default.
+* Export lifted ``throwIO`` and ``throwTo`` functions.
+
+0.1.6
+=====
+
+* Adds uncatchable panic exception throwing using Text message.
+* Removes ``printf``
+* Removes ``string-conv`` dependency so Stack build works without ``extra-deps``.
+* Brings ``Callstack`` machinery in for GHC 8.x.
+* Removes ``throw`` and ``assert`` from ``Control.Exception`` exports.
+* Removes ``unsafeShiftL`` and ``unsafeShiftR`` from ``Data.Bits`` exports.
+* Reexport ``throw`` as ``unsafeThrow`` via Unsafe module.
+* Hides all Show class functions. Only the Class itself is exported. Forbids custom instances that are not GHC derived.
+* Export`` encodeUtf8`` and ``decodeUtf8`` functions by default.
+* Adds ``unsnoc`` function.
+
+0.1.5
+=====
+
+* Initial release.
diff --git a/Exports.hs b/Exports.hs
new file mode 100644
--- /dev/null
+++ b/Exports.hs
@@ -0,0 +1,59 @@
+{-# LANGUAGE CPP #-}
+module Main
+  ( main,
+  )
+where
+
+import Control.Applicative ((<$>))
+import Control.Monad.Trans
+import Data.Foldable (concat)
+import qualified Data.List as List
+import Data.Maybe
+import Data.Ord (comparing)
+import DynFlags
+import GHC
+import GhcMonad
+import GHC.Paths
+import Outputable
+import System.FilePath.Posix
+import Prelude hiding (concat, mod)
+
+autoModule :: FilePath -> IO ()
+autoModule mod = runGhc (Just GHC.Paths.libdir) $ do
+  dflags <- GHC.getSessionDynFlags
+#if (__GLASGOW_HASKELL__ > 706)
+  _ <- setSessionDynFlags ( dflags `gopt_set` Opt_GhciSandbox )
+#else
+  _ <- setSessionDynFlags ( dflags `dopt_set` Opt_GhciSandbox )
+#endif
+  target <- guessTarget ("src" </> addExtension mod ".hs") Nothing
+  setTargets [target]
+  _ <- load LoadAllTargets
+  modSum <- getModSummary $ mkModuleName mod
+  p <- GHC.parseModule modSum
+  t <- typecheckModule p
+  let modInfo = tm_checked_module_info t
+  let exports = modInfoExports modInfo
+  exportThings <- sequence <$> mapM lookupName exports
+  let sortedThings = List.sortBy (comparing getOccName) (concat exportThings)
+  GhcMonad.liftIO (mapM_ (showThing dflags) sortedThings)
+
+showNamed :: NamedThing a => DynFlags -> a -> IO ()
+showNamed df a = do
+  let nm = showSDoc df (ppr (getOccName a))
+  let mod = showSDoc df (ppr (nameModule (getName a)))
+  putStrLn (nm ++ " from " ++ mod)
+
+showThing :: DynFlags -> TyThing -> IO ()
+showThing df (AnId a) = showNamed df a
+#if (__GLASGOW_HASKELL__ > 706)
+showThing df (AConLike a) = showNamed df a
+#endif
+showThing df (ATyCon a) = showNamed df a
+showThing _ _ = error "Should never happen."
+
+--showGhc :: (Outputable a) => a -> String
+--showGhc = showPpr unsafeGlobalDynFlags
+
+main :: IO ()
+main = autoModule "Protolude"
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2016-2019, Stephen Diehl
+Copyright (c) 2016-2020, 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/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,7 +1,10 @@
 Protolude
 =========
 
-[![Build Status](https://travis-ci.org/sdiehl/protolude.svg?branch=master)](https://travis-ci.org/sdiehl/protolude)
+[![Build Status](https://travis-ci.org/protolude/protolude.svg?branch=master)](https://travis-ci.org/sdiehl/protolude)
+[![Build Status](https://github.com/protolude/protolude/workflows/Cabal%20CI/badge.svg)](https://github.com/protolude/protolude/actions)
+[![Build Status](https://github.com/protolude/protolude/workflows/Stack%20CI/badge.svg)](https://github.com/protolude/protolude/actions)
+[![Build Status](https://github.com/protolude/protolude/workflows/Nix%20CI/badge.svg)](https://github.com/protolude/protolude/actions)
 [![Hackage](https://img.shields.io/hackage/v/protolude.svg)](https://hackage.haskell.org/package/protolude)
 
 A sensible starting Prelude for building custom Preludes.
@@ -22,7 +25,6 @@
 * Unsafe functions are prefixed with "unsafe" in separate module.
 * Compiler agnostic, GHC internal modules are abstracted out into Base.
 * ``sum`` and ``product`` are strict by default.
-* Compatibility with GHC 8.0.
 * Includes Semiring for GHC >= 7.6.
 * Includes Bifunctor for GHC >= 7.6.
 * Includes Semigroup for GHC >= 7.6.
@@ -45,7 +47,23 @@
  * GHC 8.4.1
  * GHC 8.6.1
  * GHC 8.8.1
+ * GHC 8.10.1
 
+Stack LTS:
+
+* lts-4.x
+* lts-5.x
+* lts-6.x
+* lts-7.x
+* lts-8.x
+* lts-9.x
+* lts-10.x
+* lts-11.x
+* lts-12.x
+* lts-13.x
+* lts-14.x
+* lts-15.x
+
 Usage
 -----
 
@@ -53,7 +71,7 @@
 project directory run.
 
 ```haskell
-$ stack exec ghci
+$ stack repl
 > import Protolude
 ```
 
@@ -78,11 +96,6 @@
 import Protolude
 ```
 
-Exported Functions
-------------------
-
-The list of exports can be browsed [here](http://hackage.haskell.org/package/protolude-0.2.3/docs/Protolude.html).
-
 Dependencies
 ------------
 
@@ -95,17 +108,17 @@
 | -----------         |   -------- |  -------- |
 | array               |        0.4 |       0.6 |
 | async               |        2.0 |       2.3 |
-| base                |        4.6 |      4.13 |
+| base                |        4.6 |      4.15 |
 | bytestring          |       0.10 |      0.11 |
 | containers          |        0.5 |       0.7 |
 | deepseq             |        1.3 |       1.5 |
-| ghc-prim            |        0.3 |       0.6 |
-| hashable            |        1.2 |       1.3 |
+| ghc-prim            |        0.3 |       0.7 |
+| hashable            |        1.2 |       1.4 |
 | mtl                 |        2.1 |       2.3 |
 | stm                 |        2.4 |       2.6 |
 | text                |        1.2 |       1.3 |
 | transformers        |        0.4 |       0.6 |
-|                     |            |           |
+| fail                |        4.9 |      4.10 |
 
 Structure
 ---------
@@ -168,8 +181,43 @@
 It has been renamed to ``identity`` to reserve the ``id`` identifier for the
 more common use case of business logic.
 
+* **But what if I want the partial functions?**
+
+You if you need partial functions for backwards compatibility you can use the
+`Protolude.Partial` module and mask the safe definitions as needed.
+
+```haskell
+import Protolude hiding (head)
+import Protolude.Partial (head)
+```
+
+Development Tools
+-----------------
+
+**GHC Magic**
+
+To build the `exports` management tool use:
+
+```bash
+$ cabal new-build exports --flag dev
+$ cabal run exports
+```
+
+This tool uses GHC's internal compile symbol table to generate a list of exports
+and keep the export list of protolude stable across different versions of GHC
+and base.
+
+**Continious Integration**
+
+There is a massive test suite that tests all versions of GHC 7.6 - GHC HEAD
+alongside all Stack resolvers to ensure no regressions. Any pull requests or
+patch has to pass the 40 integrity checks before being considered. Any pull
+request must keep the export list consistent across GHC and Base version and not
+have any accidental symbol dropping or drift without updating the export golden
+tests.
+
 License
 -------
 
 Released under the MIT License.
-Copyright (c) 2016-2019, Stephen Diehl
+Copyright (c) 2016-2020, Stephen Diehl
diff --git a/protolude.cabal b/protolude.cabal
--- a/protolude.cabal
+++ b/protolude.cabal
@@ -1,86 +1,118 @@
-name:                protolude
-version:             0.2.4
-synopsis:            A small prelude.
-description:         A sensible set of defaults for writing custom Preludes.
-homepage:            https://github.com/sdiehl/protolude
-license:             MIT
-license-file:        LICENSE
-author:              Stephen Diehl
-maintainer:          stephen.m.diehl@gmail.com
-copyright:           2016-2019 Stephen Diehl
-category:            Prelude
-build-type:          Simple
-cabal-version:       >=1.10
-bug-reports:         https://github.com/sdiehl/protolude/issues
-tested-with:         
-  GHC == 7.6.1,
-  GHC == 7.6.2,
-  GHC == 7.6.3,
-  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,
-  GHC == 8.0.1,
-  GHC == 8.2.1,
-  GHC == 8.4.1,
-  GHC == 8.6.1,
-  GHC == 8.8.1
-extra-source-files: README.md CHANGES.md
+name:               protolude
+version:            0.3.0
+synopsis:           A small prelude.
+description:        A sensible set of defaults for writing custom Preludes.
+homepage:           https://github.com/sdiehl/protolude
+license:            MIT
+license-file:       LICENSE
+author:             Stephen Diehl
+maintainer:         stephen.m.diehl@gmail.com
+copyright:          2016-2020 Stephen Diehl
+category:           Prelude
+build-type:         Simple
+cabal-version:      >=1.10
+bug-reports:        https://github.com/sdiehl/protolude/issues
+tested-with:
+  GHC ==7.6.1
+   || ==7.6.2
+   || ==7.6.3
+   || ==7.8.1
+   || ==7.8.2
+   || ==7.8.3
+   || ==7.8.4
+   || ==7.10.1
+   || ==7.10.2
+   || ==7.10.3
+   || ==8.0.1
+   || ==8.2.1
+   || ==8.4.1
+   || ==8.6.1
+   || ==8.8.1
+   || ==8.10.1
 
-Source-Repository head
-    type: git
-    location: git@github.com:sdiehl/protolude.git
+extra-source-files:
+  README.md
+  ChangeLog.md
 
+flag dev
+  description: Build development tools
+  manual:      True
+  default:     False
+
+source-repository head
+  type:     git
+  location: git@github.com:protolude/protolude.git
+
 library
-  exposed-modules:     
+  exposed-modules:
     Protolude
-    Unsafe
-    Debug
-    Protolude.Exceptions
-    Protolude.Base
     Protolude.Applicative
+    Protolude.Base
+    Protolude.Bifunctor
     Protolude.Bool
-    Protolude.List
-    Protolude.Monad
-    Protolude.Show
+    Protolude.CallStack
     Protolude.Conv
+    Protolude.ConvertText
+    Protolude.Debug
     Protolude.Either
-    Protolude.Functor
-    Protolude.Semiring
-    Protolude.Bifunctor
-    Protolude.CallStack
     Protolude.Error
+    Protolude.Exceptions
+    Protolude.Functor
+    Protolude.List
+    Protolude.Monad
     Protolude.Panic
+    Protolude.Partial
     Protolude.Safe
+    Protolude.Semiring
+    Protolude.Show
+    Protolude.Unsafe
 
   default-extensions:
     NoImplicitPrelude
-    OverloadedStrings
     FlexibleContexts
     MultiParamTypeClasses
+    OverloadedStrings
 
-  ghc-options:
-    -Wall
-    -fwarn-implicit-prelude
+  ghc-options:        -Wall -fwarn-implicit-prelude
+  build-depends:
+      array                >=0.4  && <0.6
+    , async                >=2.0  && <2.3
+    , base                 >=4.6  && <4.15
+    , bytestring           >=0.10 && <0.11
+    , containers           >=0.5  && <0.7
+    , deepseq              >=1.3  && <1.5
+    , ghc-prim             >=0.3  && <0.7
+    , hashable             >=1.2  && <1.4
+    , mtl                  >=2.1  && <2.3
+    , mtl-compat           >=0.2  && <0.3
+    , stm                  >=2.4  && <2.6
+    , text                 >=1.2  && <1.3
+    , transformers         >=0.2  && <0.6
+    , transformers-compat  >=0.4  && <0.7
 
-  build-depends:       
-    base                >= 4.6  && <4.14,
-    array               >= 0.4  && <0.6,
-    ghc-prim            >= 0.3  && <0.6,
-    async               >= 2.0  && <2.3,
-    deepseq             >= 1.3  && <1.5,
-    containers          >= 0.5  && <0.7,
-    hashable            >= 1.2  && <1.4,
-    transformers        >= 0.2  && <0.6,
-    text                >= 1.2  && <1.3,
-    stm                 >= 2.4  && <2.6,
-    bytestring          >= 0.10 && <0.11,
-    mtl                 >= 2.1  && <2.3,
-    mtl-compat          >= 0.2  && <0.3,
-    transformers-compat >= 0.4  && <0.7
+  if !impl(ghc >=8.0)
+    build-depends: fail ==4.9.*
 
-  hs-source-dirs:      src
-  default-language:    Haskell2010
+  hs-source-dirs:     src
+  default-language:   Haskell2010
+
+executable exports
+  main-is:          Exports.hs
+  default-language: Haskell2010
+
+  if flag(dev)
+    buildable: True
+
+  else
+    buildable: False
+
+  build-depends:
+      base          >=4.6 && <4.15
+    , directory
+    , filepath
+    , ghc
+    , ghc-paths
+    , mtl
+    , process
+    , protolude
+    , transformers
diff --git a/src/Debug.hs b/src/Debug.hs
deleted file mode 100644
--- a/src/Debug.hs
+++ /dev/null
@@ -1,69 +0,0 @@
-{-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE NoImplicitPrelude #-}
-{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
-
-module Debug (
-  undefined,
-  trace,
-  traceM,
-  traceId,
-  traceIO,
-  traceShow,
-  traceShowId,
-  traceShowM,
-  notImplemented,
-  witness,
-) where
-
-import Data.Text (Text, unpack)
-import Control.Monad (Monad, return)
-
-import qualified Protolude.Base as P
-import Protolude.Error (error)
-import Protolude.Show (Print, hPutStrLn)
-
-import System.IO(stderr)
-import System.IO.Unsafe (unsafePerformIO)
-
-{-# WARNING trace "'trace' remains in code" #-}
-trace :: Print b => b -> a -> a
-trace string expr = unsafePerformIO (do
-    hPutStrLn stderr string
-    return expr)
-
-{-# WARNING traceIO "'traceIO' remains in code" #-}
-traceIO :: Print b => b -> a -> P.IO a
-traceIO string expr = do
-    hPutStrLn stderr string
-    return expr
-
-{-# WARNING traceShow "'traceShow' remains in code" #-}
-traceShow :: P.Show a => a -> b -> b
-traceShow a b = trace (P.show a) b
-
-{-# WARNING traceShowId "'traceShowId' remains in code" #-}
-traceShowId :: P.Show a => a -> a
-traceShowId a = trace (P.show a) a
-
-{-# WARNING traceShowM "'traceShowM' remains in code" #-}
-traceShowM :: (P.Show a, Monad m) => a -> m ()
-traceShowM a = trace (P.show a) (return ())
-
-{-# WARNING traceM "'traceM' remains in code" #-}
-traceM :: (Monad m) => Text -> m ()
-traceM s = trace (unpack s) (return ())
-
-{-# WARNING traceId "'traceId' remains in code" #-}
-traceId :: Text -> Text
-traceId s = trace s s
-
-{-# WARNING notImplemented "'notImplemented' remains in code" #-}
-notImplemented :: a
-notImplemented = error "Not implemented"
-
-{-# WARNING undefined "'undefined' remains in code" #-}
-undefined :: a
-undefined = error "Prelude.undefined"
-
-witness :: a
-witness = error "Type witness should not be evaluated"
diff --git a/src/Protolude.hs b/src/Protolude.hs
--- a/src/Protolude.hs
+++ b/src/Protolude.hs
@@ -1,50 +1,158 @@
-{-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ExplicitNamespaces #-}
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
 
 module Protolude (
-  module X,
+  -- * Base functions
   module Base,
   identity,
+  pass,
+#if !MIN_VERSION_base(4,8,0)
+  (&),
+  scanl',
+#endif
+  -- * Function functions
+  module Function,
+  applyN,
+  -- * List functions
+  module List,
   map,
   uncons,
   unsnoc,
-  applyN,
-  print,
-  throwIO,
-  throwTo,
+  -- * Data Structures
+  module DataStructures,
+  -- * Show functions
+  module Show,
   show,
-  pass,
-  guarded,
-  guardedA,
-  LText,
-  LByteString,
+  print,
+  -- * Bool functions
+  module Bool,
+  -- * Monad functions
+  module Monad,
   liftIO1,
   liftIO2,
-#if !MIN_VERSION_base(4,8,0)
-  (&),
-  scanl',
+  -- * Functor functions
+  module Functor,
+  -- * Either functions
+  module Either,
+  -- * Applicative functions
+  module Applicative,
+  guarded,
+  guardedA,
+  -- * String conversion
+  module ConvertText,
+  -- * Debug functions
+  module Debug,
+
+  -- * Panic functions
+  module Panic,
+  -- * Exception functions
+  module Exception,
+  Protolude.throwIO,
+  Protolude.throwTo,
+  -- * Semiring functions
+  module Semiring,
+
+  -- * String functions
+  module String,
+  -- * Safe functions
+  module Safe,
+  -- * Eq functions
+  module Eq,
+  -- * Ord functions
+  module Ord,
+  -- * Traversable functions
+  module Traversable,
+  -- * Foldable functions
+  module Foldable,
+  -- * Semigroup functions
+#if MIN_VERSION_base(4,9,0)
+  module Semigroup,
 #endif
+  -- * Monoid functions
+  module Monoid,
+  -- * Bifunctor functions
+  module Bifunctor,
+  -- * Bifunctor functions
+  module Hashable,
+
+  -- * Deepseq functions
+  module DeepSeq,
+
+  -- * Tuple functions
+  module Tuple,
+
+  module Typeable,
+
+#if MIN_VERSION_base(4,7,0)
+  -- * Typelevel programming
+  module Typelevel,
+#endif
+
+  -- * Monads
+  module Fail,
+  module State,
+  module Reader,
+  module Except,
+  module Trans,
+  module ST,
+  module STM,
+
+  -- * Integers
+  module Int,
+  module Bits,
+
+  -- * Complex functions
+  module Complex,
+
+  -- * Char functions
+  module Char,
+
+  -- * Maybe functions
+  module Maybe,
+
+  -- * Generics functions
+  module Generics,
+
+  -- * ByteString functions
+  module ByteString,
+  LByteString,
+
+  -- * Text functions
+  module Text,
+  LText,
+
+  -- * Read functions
+  module Read,
+
+  -- * System functions
+  module System,
   die,
+
+  -- * Concurrency functions
+  module Concurrency,
+
+  -- * Foreign functions
+  module Foreign,
 ) where
 
 -- Protolude module exports.
-import Debug as X
-import Protolude.List as X
-import Protolude.Show as X
-import Protolude.Bool as X
-import Protolude.Monad as X
-import Protolude.Functor as X
-import Protolude.Either as X
-import Protolude.Applicative as X
-import Protolude.Conv as X
-import Protolude.Panic as X
-import Protolude.Exceptions as X
-import Protolude.Semiring as X
+import Protolude.Debug as Debug
+import Protolude.List as List
+import Protolude.Show as Show
+import Protolude.Bool as Bool
+import Protolude.Monad as Monad
+import Protolude.Functor as Functor
+import Protolude.Either as Either
+import Protolude.Applicative as Applicative
+import Protolude.ConvertText as ConvertText
+import Protolude.Panic as Panic
+import Protolude.Exceptions as Exception
+import Protolude.Semiring as Semiring
 
 import Protolude.Base as Base hiding (
     putStr           -- Overriden by Show.putStr
@@ -61,10 +169,10 @@
 
 -- Used for 'show', not exported.
 import Data.String (String)
-import Data.String as X (IsString)
+import Data.String as String (IsString)
 
 -- Maybe'ized version of partial functions
-import Protolude.Safe as X (
+import Protolude.Safe as Safe (
     headMay
   , headDef
   , initMay
@@ -87,11 +195,11 @@
   )
 
 -- Applicatives
-import Control.Applicative as X (
+import Control.Applicative as Applicative (
     Applicative(..)
   , Alternative(..)
-  , Const(..)
-  , ZipList(..)
+  , Const(Const,getConst)
+  , ZipList(ZipList,getZipList)
   , (<**>)
   , liftA
   , liftA2
@@ -100,32 +208,63 @@
   )
 
 -- Base typeclasses
-import Data.Eq as X (
+import Data.Eq as Eq (
     Eq(..)
   )
-import Data.Ord as X (
+import Data.Ord as Ord (
     Ord(..)
-  , Ordering(..)
-  , Down(..)
+  , Ordering(LT,EQ,GT)
+  , Down(Down)
   , comparing
   )
-import Data.Traversable as X
-import Data.Foldable as X hiding (
-    foldr1
-  , foldl1
-  , product
-  , sum
+import Data.Traversable as Traversable
+import Data.Foldable as Foldable (
+    Foldable,
+    fold,
+    foldMap,
+    foldr,
+    foldr',
+    foldl,
+    foldl',
+    toList,
+#if MIN_VERSION_base(4,8,0)
+    null,
+    length,
+#endif
+    elem,
+    maximum,
+    minimum,
+    foldrM,
+    foldlM,
+    traverse_,
+    for_,
+    mapM_,
+    forM_,
+    sequence_,
+    sequenceA_,
+    asum,
+    msum,
+    concat,
+    concatMap,
+    and,
+    or,
+    any,
+    all,
+    maximumBy,
+    minimumBy,
+    notElem,
+    find,
   )
-import Data.Functor.Identity as X (
-    Identity(..)
+import Data.Functor.Identity as Functor (
+    Identity(Identity, runIdentity)
   )
 
 #if MIN_VERSION_base(4,9,0)
-import Data.List.NonEmpty as X (
-    NonEmpty(..)
+import Data.List.NonEmpty as List (
+    NonEmpty((:|))
   , nonEmpty
   )
-import Data.Semigroup as X (
+import Data.Semigroup as Semigroup (
     Semigroup(sconcat, stimes)
   , WrappedMonoid
   , Option(..)
@@ -139,16 +278,16 @@
   )
 #endif
 
-import Data.Monoid as X
+import Data.Monoid as Monoid
 
 #if !MIN_VERSION_base(4,8,0)
-import Protolude.Bifunctor as X (Bifunctor(..))
+import Protolude.Bifunctor as Bifunctor (Bifunctor(bimap, first, second))
 #else
-import Data.Bifunctor as X (Bifunctor(..))
+import Data.Bifunctor as Bifunctor (Bifunctor(bimap, first, second))
 #endif
 
 -- Deepseq
-import Control.DeepSeq as X (
+import Control.DeepSeq as DeepSeq (
     NFData(..)
   , ($!!)
   , deepseq
@@ -156,7 +295,7 @@
   )
 
 -- Data structures
-import Data.Tuple as X (
+import Data.Tuple as Tuple (
     fst
   , snd
   , curry
@@ -164,7 +303,7 @@
   , swap
   )
 
-import Data.List as X (
+import Data.List as List (
     splitAt
   , break
   , intercalate
@@ -211,39 +350,43 @@
 #endif
 
 -- Hashing
-import Data.Hashable as X (
+import Data.Hashable as Hashable (
     Hashable
   , hash
   , hashWithSalt
   , hashUsing
   )
 
-import Data.Map as X (Map)
-import Data.Set as X (Set)
-import Data.Sequence as X (Seq)
-import Data.IntMap as X (IntMap)
-import Data.IntSet as X (IntSet)
-
-#if MIN_VERSION_base(4,7,0)
-import Data.Proxy as X (
-    Proxy(..)
-  )
+import Data.Map as DataStructures (Map)
+import Data.Set as DataStructures (Set)
+import Data.Sequence as DataStructures (Seq)
+import Data.IntMap as DataStructures (IntMap)
+import Data.IntSet as DataStructures (IntSet)
 
-import Data.Typeable as X (
+import Data.Typeable as Typeable (
     TypeRep
   , Typeable
-  , typeRep
+  , typeOf
   , cast
+  , gcast
+#if MIN_VERSION_base(4,7,0)
+  , typeRep
   , eqT
+#endif
   )
 
-import Data.Type.Coercion as X (
+#if MIN_VERSION_base(4,7,0)
+import Data.Proxy as Typelevel (
+    Proxy(..)
+  )
+
+import Data.Type.Coercion as Typelevel (
     Coercion(..)
   , coerceWith
   , repr
   )
 
-import Data.Type.Equality as X (
+import Data.Type.Equality as Typelevel (
     (:~:)(..)
   , type (==)
   , sym
@@ -255,15 +398,19 @@
 #endif
 
 #if MIN_VERSION_base(4,8,0)
-import Data.Void as X (
+import Data.Void as Typelevel (
     Void
   , absurd
   , vacuous
   )
 #endif
 
+import Control.Monad.Fail as Fail (
+    MonadFail
+  )
+
 -- Monad transformers
-import Control.Monad.State as X (
+import Control.Monad.State as State (
     MonadState
   , State
   , StateT(StateT)
@@ -283,7 +430,7 @@
   , evalStateT
   )
 
-import Control.Monad.Reader as X (
+import Control.Monad.Reader as Reader (
     MonadReader
   , Reader
   , ReaderT(ReaderT)
@@ -295,12 +442,12 @@
   , runReaderT
   )
 
-import Control.Monad.Trans.Except as X (
+import Control.Monad.Trans.Except as Except (
     throwE
   , catchE
   )
 
-import Control.Monad.Except as X (
+import Control.Monad.Except as Except (
     MonadError
   , Except
   , ExceptT(ExceptT)
@@ -314,25 +461,60 @@
   , withExceptT
   )
 
-import Control.Monad.Trans as X (
+import Control.Monad.Trans as Trans (
     MonadIO
   , lift
   , liftIO
   )
 
 -- Base types
-import Data.Int as X (
+import Data.Int as Int (
     Int
   , Int8
   , Int16
   , Int32
   , Int64
   )
-import Data.Bits as X hiding (
-    unsafeShiftL
-  , unsafeShiftR
+import Data.Bits as Bits (
+  Bits,
+  (.&.),
+  (.|.),
+  xor,
+  complement,
+  shift,
+  rotate,
+#if MIN_VERSION_base(4,7,0)
+  zeroBits,
+#endif
+  bit,
+  setBit,
+  clearBit,
+  complementBit,
+  testBit,
+#if MIN_VERSION_base(4,7,0)
+  bitSizeMaybe,
+#endif
+  bitSize,
+  isSigned,
+  shiftL,
+  shiftR,
+  rotateL,
+  rotateR,
+  popCount,
+#if MIN_VERSION_base(4,7,0)
+  FiniteBits,
+  finiteBitSize,
+  bitDefault,
+  testBitDefault,
+  popCountDefault,
+#endif
+#if MIN_VERSION_base(4,8,0)
+  toIntegralSized,
+  countLeadingZeros,
+  countTrailingZeros,
+#endif
   )
-import Data.Word as X (
+import Data.Word as Bits (
     Word
   , Word8
   , Word16
@@ -345,8 +527,8 @@
 #endif
   )
 
-import Data.Either as X (
-    Either(..)
+import Data.Either as Either (
+    Either(Left,Right)
   , either
   , lefts
   , rights
@@ -357,8 +539,8 @@
 #endif
   )
 
-import Data.Complex as X (
-    Complex(..)
+import Data.Complex as Complex (
+    Complex((:+))
   , realPart
   , imagPart
   , mkPolar
@@ -368,11 +550,47 @@
   , phase
   , conjugate
   )
-import Data.Char as X (chr)
-import Data.Bool as X hiding (bool)
-import Data.Maybe as X hiding (fromJust)
+import Data.Char as Char (
+    Char
+  , ord
+  , chr
+  , digitToInt
+  , intToDigit
+  , toUpper
+  , toLower
+  , toTitle
+  , isAscii
+  , isLetter
+  , isDigit
+  , isHexDigit
+  , isPrint
+  , isAlpha
+  , isAlphaNum
+  , isUpper
+  , isLower
+  , isSpace
+  , isControl
+  )
+import Data.Bool as Bool (
+  Bool(True, False),
+  (&&),
+  (||),
+  not,
+  otherwise
+  )
+import Data.Maybe as Maybe (
+    Maybe(Nothing, Just)
+  , maybe
+  , isJust
+  , isNothing
+  , fromMaybe
+  , listToMaybe
+  , maybeToList
+  , catMaybes
+  , mapMaybe
+  )
 
-import Data.Function as X (
+import Data.Function as Function (
     const
   , (.)
   , ($)
@@ -385,7 +603,7 @@
   )
 
 -- Genericss
-import GHC.Generics as X (
+import GHC.Generics as Generics (
     Generic(..)
   , Generic1
   , Rep
@@ -414,10 +632,10 @@
 
 -- ByteString
 import qualified Data.ByteString.Lazy
-import Data.ByteString as X (ByteString)
+import Data.ByteString as ByteString (ByteString)
 
 -- Text
-import Data.Text as X (
+import Data.Text as Text (
     Text
   , lines
   , words
@@ -426,7 +644,7 @@
   )
 import qualified Data.Text.Lazy
 
-import Data.Text.IO as X (
+import Data.Text.IO as Text (
     getLine
   , getContents
   , interact
@@ -435,19 +653,19 @@
   , appendFile
   )
 
-import Data.Text.Lazy as X (
+import Data.Text.Lazy as Text (
     toStrict
   , fromStrict
   )
 
-import Data.Text.Encoding as X (
+import Data.Text.Encoding as Text (
     encodeUtf8
   , decodeUtf8
   , decodeUtf8'
   , decodeUtf8With
   )
 
-import Data.Text.Encoding.Error as X (
+import Data.Text.Encoding.Error as Text (
     OnDecodeError
   , OnError
   , UnicodeException
@@ -458,15 +676,15 @@
   )
 
 -- IO
-import System.Environment as X (getArgs)
+import System.Environment as System (getArgs)
 import qualified System.Exit
-import System.Exit as X (
+import System.Exit as System (
     ExitCode(..)
   , exitWith
   , exitFailure
   , exitSuccess
   )
-import System.IO as X (
+import System.IO as System (
     Handle
   , FilePath
   , IOMode(..)
@@ -478,24 +696,92 @@
   )
 
 -- ST
-import Control.Monad.ST as X (
+import Control.Monad.ST as ST (
     ST
   , runST
   , fixST
   )
 
 -- Concurrency and Parallelism
-import Control.Exception as X hiding (
-    throw    -- Impure throw is forbidden.
-  , throwIO
-  , throwTo
-  , assert
-  , Handler(..)
+import Control.Exception as Exception (
+    Exception,
+    toException,
+    fromException,
+#if MIN_VERSION_base(4,8,0)
+    displayException,
+#endif
+    SomeException(SomeException)
+  , IOException
+  , ArithException(
+    Overflow,
+    Underflow,
+    LossOfPrecision,
+    DivideByZero,
+    Denormal,
+    RatioZeroDenominator
+    )
+  , ArrayException(IndexOutOfBounds, UndefinedElement)
+  , AssertionFailed(AssertionFailed)
+#if MIN_VERSION_base(4,7,0)
+  , SomeAsyncException(SomeAsyncException)
+  , asyncExceptionToException
+  , asyncExceptionFromException
+#endif
+  , AsyncException(StackOverflow, HeapOverflow, ThreadKilled, UserInterrupt)
+  , NonTermination(NonTermination)
+  , NestedAtomically(NestedAtomically)
+  , BlockedIndefinitelyOnMVar(BlockedIndefinitelyOnMVar)
+  , BlockedIndefinitelyOnSTM(BlockedIndefinitelyOnSTM)
+#if MIN_VERSION_base(4,8,0)
+  , AllocationLimitExceeded(AllocationLimitExceeded)
+#endif
+#if MIN_VERSION_base(4,10,0)
+  , CompactionFailed(CompactionFailed)
+#endif
+  , Deadlock(Deadlock)
+  , NoMethodError(NoMethodError)
+  , PatternMatchFail(PatternMatchFail)
+  , RecConError(RecConError)
+  , RecSelError(RecSelError)
+  , RecUpdError(RecUpdError)
+#if MIN_VERSION_base(4,9,0)
+  , ErrorCall(ErrorCall, ErrorCallWithLocation)
+#else
+  , ErrorCall(ErrorCall)
+#endif
+#if MIN_VERSION_base(4,9,0)
+  , TypeError(TypeError)
+#endif
+  , ioError
+  , catch
+  , catches
+  , Handler(Handler)
+  , catchJust
+  , handle
+  , handleJust
+  , try
+  , tryJust
+  , evaluate
+  , mapException
+  , mask
+  , mask_
+  , uninterruptibleMask
+  , uninterruptibleMask_
+  , MaskingState(..)
+  , getMaskingState
+#if MIN_VERSION_base(4,9,0)
+  , interruptible
+#endif
+  , allowInterrupt
+  , bracket
+  , bracket_
+  , bracketOnError
+  , finally
+  , onException
   )
-
-import qualified Control.Exception
+import qualified Control.Exception as PException
 
-import Control.Monad.STM as X (
+import Control.Monad.STM as STM (
     STM
   , atomically
 #if !(MIN_VERSION_stm(2,5,0))
@@ -508,11 +794,84 @@
   , throwSTM
   , catchSTM
   )
-import Control.Concurrent as X hiding (
-    throwTo
+
+import Control.Concurrent.MVar as Concurrency (
+    MVar
+  , newEmptyMVar
+  , newMVar
+  , takeMVar
+  , putMVar
+  , readMVar
+  , swapMVar
+  , tryTakeMVar
+  , tryPutMVar
+  , isEmptyMVar
+  , withMVar
+#if MIN_VERSION_base(4,7,0)
+  , withMVarMasked
+#endif
+  , modifyMVar_
+  , modifyMVar
+  , modifyMVarMasked_
+  , modifyMVarMasked
+#if MIN_VERSION_base(4,7,0)
+  , tryReadMVar
+  , mkWeakMVar
+#endif
+  , addMVarFinalizer
+  )
+import Control.Concurrent.Chan as Concurrency (
+    Chan
+  , newChan
+  , writeChan
+  , readChan
+  , dupChan
+  , getChanContents
+  , writeList2Chan
+  )
+import Control.Concurrent.QSem as Concurrency (
+    QSem
+  , newQSem
+  , waitQSem
+  , signalQSem
+  )
+import Control.Concurrent.QSemN as Concurrency (
+    QSemN
+  , newQSemN
+  , waitQSemN
+  , signalQSemN
+  )
+import Control.Concurrent as Concurrency (
+    ThreadId
+  , forkIO
+  , forkFinally
+  , forkIOWithUnmask
+  , killThread
+  , forkOn
+  , forkOnWithUnmask
+  , getNumCapabilities
+  , setNumCapabilities
+  , threadCapability
   , yield
+  , threadDelay
+  , threadWaitRead
+  , threadWaitWrite
+#if MIN_VERSION_base(4,7,0)
+  , threadWaitReadSTM
+  , threadWaitWriteSTM
+#endif
+  , rtsSupportsBoundThreads
+  , forkOS
+#if MIN_VERSION_base(4,9,0)
+  , forkOSWithUnmask
+#endif
+  , isCurrentThreadBound
+  , runInBoundThread
+  , runInUnboundThread
+  , mkWeakThreadId
+  , myThreadId
   )
-import Control.Concurrent.Async as X (
+import Control.Concurrent.Async as Concurrency (
     Async(..)
   , Concurrently(..)
   , async
@@ -544,12 +903,12 @@
   , concurrently
   )
 
-import Foreign.Ptr as X (IntPtr, WordPtr)
-import Foreign.Storable as X (Storable)
-import Foreign.StablePtr as X (StablePtr)
+import Foreign.Ptr as Foreign (IntPtr, WordPtr)
+import Foreign.Storable as Foreign (Storable)
+import Foreign.StablePtr as Foreign (StablePtr)
 
 -- Read instances hiding unsafe builtins (read)
-import Text.Read as X (
+import Text.Read as Read (
     Read
   , reads
   , readMaybe
@@ -568,44 +927,52 @@
 x & f = f x
 #endif
 
+-- | The identity function, returns the give value unchanged.
 identity :: a -> a
 identity x = x
 
-map :: Functor f => (a -> b) -> f a -> f b
-map = fmap
+map :: Functor.Functor f => (a -> b) -> f a -> f b
+map = Functor.fmap
 
 uncons :: [a] -> Maybe (a, [a])
 uncons [] = Nothing
 uncons (x:xs) = Just (x, xs)
 
 unsnoc :: [x] -> Maybe ([x],x)
-unsnoc = foldr go Nothing
+unsnoc = Foldable.foldr go Nothing
   where
     go x mxs = Just (case mxs of
        Nothing -> ([], x)
        Just (xs, e) -> (x:xs, e))
 
+-- | Apply a function n times to a given value
 applyN :: Int -> (a -> a) -> a -> a
-applyN n f = X.foldr (.) identity (X.replicate n f)
+applyN n f = Foldable.foldr (.) identity (List.replicate n f)
 
-print :: (X.MonadIO m, PBase.Show a) => a -> m ()
+-- | The print function outputs a value of any printable type to the standard
+-- output device. Printable types are those that are instances of class Show;
+-- print converts values to strings for output using the show operation and adds
+-- a newline.
+print :: (Trans.MonadIO m, PBase.Show a) => a -> m ()
 print = liftIO . PBase.print
 
-throwIO :: (X.MonadIO m, Exception e) => e -> m a
-throwIO = liftIO . Control.Exception.throwIO
+-- | Lifted throwIO
+throwIO :: (Trans.MonadIO m, Exception e) => e -> m a
+throwIO = liftIO . PException.throwIO
 
-throwTo :: (X.MonadIO m, Exception e) => ThreadId -> e -> m ()
-throwTo tid e = liftIO (Control.Exception.throwTo tid e)
+-- | Lifted throwTo
+throwTo :: (Trans.MonadIO m, Exception e) => ThreadId -> e -> m ()
+throwTo tid e = liftIO (PException.throwTo tid e)
 
 -- | Do nothing returning unit inside applicative.
 pass :: Applicative f => f ()
 pass = pure ()
 
 guarded :: (Alternative f) => (a -> Bool) -> a -> f a
-guarded p x = X.bool empty (pure x) (p x)
+guarded p x = Bool.bool empty (pure x) (p x)
 
-guardedA :: (Functor f, Alternative t) => (a -> f Bool) -> a -> f (t a)
-guardedA p x = X.bool empty (pure x) <$> p x
+guardedA :: (Functor.Functor f, Alternative t) => (a -> f Bool) -> a -> f (t a)
+guardedA p x = Bool.bool empty (pure x) `Functor.fmap` p x
 
 -- | Lift an 'IO' operation with 1 argument into another monad
 liftIO1 :: MonadIO m => (a -> IO b) -> a -> m b
@@ -615,18 +982,18 @@
 liftIO2 :: MonadIO m => (a -> b -> IO c) -> a -> b -> m c
 liftIO2 = ((.).(.)) liftIO
 
-show :: (Show a, StringConv String b) => a -> b
-show x = toS (PBase.show x)
+show :: (Show a, ConvertText String b) => a -> b
+show x = ConvertText.toS (PBase.show x)
 {-# SPECIALIZE show :: Show  a => a -> Text  #-}
 {-# SPECIALIZE show :: Show  a => a -> LText  #-}
-{-# SPECIALIZE show :: Show  a => a -> ByteString  #-}
-{-# SPECIALIZE show :: Show  a => a -> LByteString  #-}
 {-# SPECIALIZE show :: Show  a => a -> String  #-}
 
 #if MIN_VERSION_base(4,8,0)
+-- | Terminate main process with failure
 die :: Text -> IO a
-die err = System.Exit.die (toS err)
+die err = System.Exit.die (ConvertText.toS err)
 #else
+-- | Terminate main process with failure
 die :: Text -> IO a
 die err = hPutStrLn stderr err >> exitFailure
 #endif
diff --git a/src/Protolude/Applicative.hs b/src/Protolude/Applicative.hs
--- a/src/Protolude/Applicative.hs
+++ b/src/Protolude/Applicative.hs
@@ -1,20 +1,21 @@
 {-# LANGUAGE Safe #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 
-module Protolude.Applicative (
-  orAlt,
-  orEmpty,
-  eitherA,
-  purer,
-  liftAA2,
-  (<<*>>),
-) where
+module Protolude.Applicative
+  ( orAlt,
+    orEmpty,
+    eitherA,
+    purer,
+    liftAA2,
+    (<<*>>),
+  )
+where
 
+import Control.Applicative
 import Data.Bool (Bool)
+import Data.Either (Either (Left, Right))
 import Data.Function ((.))
-import Data.Either (Either(..))
-import Data.Monoid (Monoid(..))
-import Control.Applicative
+import Data.Monoid (Monoid (mempty))
 
 orAlt :: (Alternative f, Monoid a) => f a -> f a
 orAlt f = f <|> pure mempty
@@ -33,5 +34,5 @@
 
 infixl 4 <<*>>
 
-(<<*>>) :: (Applicative f, Applicative g)  => f (g (a -> b)) -> f (g a) -> f (g b)
+(<<*>>) :: (Applicative f, Applicative g) => f (g (a -> b)) -> f (g a) -> f (g b)
 (<<*>>) = liftA2 (<*>)
diff --git a/src/Protolude/Base.hs b/src/Protolude/Base.hs
--- a/src/Protolude/Base.hs
+++ b/src/Protolude/Base.hs
@@ -1,11 +1,12 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE MagicHash #-}
 {-# LANGUAGE Unsafe #-}
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ExplicitNamespaces #-}
 
 module Protolude.Base (
-  module X,
+  module Base,
   ($!),
 ) where
 
@@ -13,35 +14,118 @@
 #if defined(__GLASGOW_HASKELL__) && ( __GLASGOW_HASKELL__ >= 600 )
 
 -- Base GHC types
-import GHC.Num as X (
-    Num(..)
+import GHC.Num as Base (
+    Num(
+      (+),
+      (-),
+      (*),
+      negate,
+      abs,
+      signum,
+      fromInteger
+    )
   , Integer
   , subtract
   )
-import GHC.Enum as X (
-    Bounded(..)
-  , Enum(..)
+import GHC.Enum as Base (
+    Bounded(minBound, maxBound)
+  , Enum(
+      succ,
+      pred,
+      toEnum,
+      fromEnum,
+      enumFrom,
+      enumFromThen,
+      enumFromTo,
+      enumFromThenTo
+    )
   , boundedEnumFrom
   , boundedEnumFromThen
   )
-import GHC.Real as X
-import GHC.Float as X (
-    Float(..)
-  , Double(..)
+import GHC.Real as Base (
+    (%)
+  , (/)
+  , Fractional
+  , Integral
+  , Ratio
+  , Rational
+  , Real
+  , RealFrac
+  , (^)
+  , (^%^)
+  , (^^)
+  , (^^%^^)
+  , ceiling
+  , denominator
+  , div
+  , divMod
+#if MIN_VERSION_base(4,7,0)
+  , divZeroError
+#endif
+  , even
+  , floor
+  , fromIntegral
+  , fromRational
+  , gcd
+#if MIN_VERSION_base(4,9,0)
+  , gcdInt'
+  , gcdWord'
+#endif
+  , infinity
+  , integralEnumFrom
+  , integralEnumFromThen
+  , integralEnumFromThenTo
+  , integralEnumFromTo
+  , lcm
+  , mod
+  , notANumber
+  , numerator
+  , numericEnumFrom
+  , numericEnumFromThen
+  , numericEnumFromThenTo
+  , numericEnumFromTo
+  , odd
+#if MIN_VERSION_base(4,7,0)
+  , overflowError
+#endif
+  , properFraction
+  , quot
+  , quotRem
+  , ratioPrec
+  , ratioPrec1
+#if MIN_VERSION_base(4,7,0)
+  , ratioZeroDenominatorError
+#endif
+  , realToFrac
+  , recip
+  , reduce
+  , rem
+  , round
+  , showSigned
+  , toInteger
+  , toRational
+  , truncate
+#if MIN_VERSION_base(4,12,0)
+  , underflowError
+#endif
+  )
+import GHC.Float as Base (
+    Float(F#)
+  , Double(D#)
   , Floating (..)
   , RealFloat(..)
   , showFloat
   , showSignedFloat
   )
-import GHC.Show as X (
-    Show(..)
+import GHC.Show as Base (
+    Show(showsPrec, show, showList)
   )
-import GHC.Exts as X (
+import GHC.Exts as Base (
     Constraint
   , Ptr
   , FunPtr
   )
-import GHC.Base as X (
+import GHC.Base as Base (
     (++)
   , seq
   , asTypeOf
@@ -52,13 +136,13 @@
   )
 
 -- Exported for lifting into new functions.
-import System.IO as X (
+import System.IO as Base (
     print
   , putStr
   , putStrLn
   )
 
-import GHC.Types as X (
+import GHC.Types as Base (
     Bool
   , Char
   , Int
@@ -71,22 +155,22 @@
   )
 
 #if ( __GLASGOW_HASKELL__ >= 710 )
-import GHC.StaticPtr as X (StaticPtr)
+import GHC.StaticPtr as Base (StaticPtr)
 #endif
 
 #if ( __GLASGOW_HASKELL__ >= 800 )
-import GHC.OverloadedLabels as X (
-    IsLabel(..)
+import GHC.OverloadedLabels as Base (
+    IsLabel(fromLabel)
   )
 
-import GHC.ExecutionStack as X (
-    Location(..)
-  , SrcLoc(..)
+import GHC.ExecutionStack as Base (
+    Location(Location, srcLoc, objectName, functionName)
+  , SrcLoc(SrcLoc, sourceColumn, sourceLine, sourceColumn)
   , getStackTrace
   , showStackTrace
   )
 
-import GHC.Stack as X (
+import GHC.Stack as Base (
     CallStack
   , type HasCallStack
   , callStack
@@ -99,11 +183,11 @@
 #endif
 
 #if ( __GLASGOW_HASKELL__ >= 710 )
-import GHC.TypeLits as X (
+import GHC.TypeLits as Base (
     Symbol
-  , SomeSymbol(..)
+  , SomeSymbol(SomeSymbol)
   , Nat
-  , SomeNat(..)
+  , SomeNat(SomeNat)
   , CmpNat
   , KnownSymbol
   , KnownNat
@@ -115,13 +199,13 @@
 #endif
 
 #if ( __GLASGOW_HASKELL__ >= 802 )
-import GHC.Records as X (
-    HasField(..)
+import GHC.Records as Base (
+    HasField(getField)
   )
 #endif
 
 #if ( __GLASGOW_HASKELL__ >= 800 )
-import Data.Kind as X (
+import Data.Kind as Base (
   type Type
 #if ( __GLASGOW_HASKELL__ < 805 )
   , type (*)
diff --git a/src/Protolude/Bifunctor.hs b/src/Protolude/Bifunctor.hs
--- a/src/Protolude/Bifunctor.hs
+++ b/src/Protolude/Bifunctor.hs
@@ -1,13 +1,17 @@
 {-# LANGUAGE Safe #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 
-module Protolude.Bifunctor (
-  Bifunctor(..)
-) where
+module Protolude.Bifunctor
+  ( Bifunctor,
+    bimap,
+    first,
+    second,
+  )
+where
 
-import Data.Function (id, (.))
-import Data.Either (Either(..))
-import Control.Applicative ( Const(..) )
+import Control.Applicative (Const (Const))
+import Data.Either (Either (Left, Right))
+import Data.Function ((.), id)
 
 class Bifunctor p where
   {-# MINIMAL bimap | first, second #-}
diff --git a/src/Protolude/Bool.hs b/src/Protolude/Bool.hs
--- a/src/Protolude/Bool.hs
+++ b/src/Protolude/Bool.hs
@@ -13,7 +13,7 @@
 , (<||>)
 ) where
 
-import Data.Bool (Bool(..), (&&), (||))
+import Data.Bool (Bool(True, False), (&&), (||))
 import Data.Function (flip)
 import Control.Applicative(Applicative, liftA2)
 import Control.Monad (Monad, MonadPlus, return, when, unless, guard, (>>=), (=<<))
diff --git a/src/Protolude/Conv.hs b/src/Protolude/Conv.hs
--- a/src/Protolude/Conv.hs
+++ b/src/Protolude/Conv.hs
@@ -2,11 +2,14 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE TypeSynonymInstances #-}
 
+-- | An alternative to 'Protolude.ConvertText' that includes
+-- partial conversions. Not re-exported by 'Protolude'.
 module Protolude.Conv (
-  StringConv (..)
+  StringConv
+, strConv
 , toS
 , toSL
-, Leniency (..)
+, Leniency (Lenient, Strict)
 ) where
 
 import Data.ByteString.Char8      as B
@@ -18,8 +21,8 @@
 import Data.Text.Lazy.Encoding    as LT
 
 import Protolude.Base
-import Data.Eq (Eq(..))
-import Data.Ord (Ord(..))
+import Data.Eq (Eq)
+import Data.Ord (Ord)
 import Data.Function ((.), id)
 import Data.String (String)
 import Control.Applicative (pure)
diff --git a/src/Protolude/ConvertText.hs b/src/Protolude/ConvertText.hs
new file mode 100644
--- /dev/null
+++ b/src/Protolude/ConvertText.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE Safe #-}
+
+-- | Non-partial text conversion typeclass and functions.
+-- For an alternative with partial conversions import 'Protolude.Conv'.
+module Protolude.ConvertText (
+  ConvertText (toS)
+, toUtf8
+, toUtf8Lazy
+) where
+
+import qualified Data.ByteString      as B
+import qualified Data.ByteString.Lazy as LB
+import qualified Data.Text            as T
+import qualified Data.Text.Lazy       as LT
+
+import Data.Function (id, (.))
+import Data.String (String)
+import Data.Text.Encoding (encodeUtf8)
+
+-- | Convert from one Unicode textual type to another. Not for serialization/deserialization,
+-- so doesn't have instances for bytestrings.
+class ConvertText a b where
+  toS :: a -> b
+
+instance ConvertText String String where toS = id
+instance ConvertText String T.Text where toS = T.pack
+instance ConvertText String LT.Text where toS = LT.pack
+
+instance ConvertText T.Text String where toS = T.unpack
+instance ConvertText T.Text LT.Text where toS = LT.fromStrict
+instance ConvertText T.Text T.Text where toS = id
+
+instance ConvertText LT.Text String where toS = LT.unpack
+instance ConvertText LT.Text T.Text where toS = LT.toStrict
+instance ConvertText LT.Text LT.Text where toS = id
+
+toUtf8 :: ConvertText a T.Text => a -> B.ByteString
+toUtf8 =
+  encodeUtf8 . toS
+
+toUtf8Lazy :: ConvertText a T.Text => a -> LB.ByteString
+toUtf8Lazy =
+  LB.fromStrict . encodeUtf8 . toS
diff --git a/src/Protolude/Debug.hs b/src/Protolude/Debug.hs
new file mode 100644
--- /dev/null
+++ b/src/Protolude/Debug.hs
@@ -0,0 +1,69 @@
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
+
+module Protolude.Debug (
+  undefined,
+  trace,
+  traceM,
+  traceId,
+  traceIO,
+  traceShow,
+  traceShowId,
+  traceShowM,
+  notImplemented,
+  witness,
+) where
+
+import Data.Text (Text, unpack)
+import Control.Monad (Monad, return)
+
+import qualified Protolude.Base as P
+import Protolude.Error (error)
+import Protolude.Show (Print, hPutStrLn)
+
+import System.IO(stderr)
+import System.IO.Unsafe (unsafePerformIO)
+
+{-# WARNING trace "'trace' remains in code" #-}
+trace :: Print b => b -> a -> a
+trace string expr = unsafePerformIO (do
+    hPutStrLn stderr string
+    return expr)
+
+{-# WARNING traceIO "'traceIO' remains in code" #-}
+traceIO :: Print b => b -> a -> P.IO a
+traceIO string expr = do
+    hPutStrLn stderr string
+    return expr
+
+{-# WARNING traceShow "'traceShow' remains in code" #-}
+traceShow :: P.Show a => a -> b -> b
+traceShow a b = trace (P.show a) b
+
+{-# WARNING traceShowId "'traceShowId' remains in code" #-}
+traceShowId :: P.Show a => a -> a
+traceShowId a = trace (P.show a) a
+
+{-# WARNING traceShowM "'traceShowM' remains in code" #-}
+traceShowM :: (P.Show a, Monad m) => a -> m ()
+traceShowM a = trace (P.show a) (return ())
+
+{-# WARNING traceM "'traceM' remains in code" #-}
+traceM :: (Monad m) => Text -> m ()
+traceM s = trace (unpack s) (return ())
+
+{-# WARNING traceId "'traceId' remains in code" #-}
+traceId :: Text -> Text
+traceId s = trace s s
+
+{-# WARNING notImplemented "'notImplemented' remains in code" #-}
+notImplemented :: a
+notImplemented = error "Not implemented"
+
+{-# WARNING undefined "'undefined' remains in code" #-}
+undefined :: a
+undefined = error "Prelude.undefined"
+
+witness :: a
+witness = error "Type witness should not be evaluated"
diff --git a/src/Protolude/Either.hs b/src/Protolude/Either.hs
--- a/src/Protolude/Either.hs
+++ b/src/Protolude/Either.hs
@@ -15,8 +15,8 @@
 
 import Data.Function (const)
 import Data.Monoid (Monoid, mempty)
-import Data.Maybe (Maybe(..), maybe)
-import Data.Either (Either(..), either)
+import Data.Maybe (Maybe(Nothing, Just), maybe)
+import Data.Either (Either(Left, Right), either)
 #if MIN_VERSION_base(4,10,0)
 import Data.Either (fromLeft, fromRight)
 #else
diff --git a/src/Protolude/Error.hs b/src/Protolude/Error.hs
--- a/src/Protolude/Error.hs
+++ b/src/Protolude/Error.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE CPP #-}
-{-# LANGUAGE MagicHash #-}
 {-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE MagicHash #-}
 {-# LANGUAGE ImplicitParams #-}
 {-# LANGUAGE ExistentialQuantification #-}
 #if ( __GLASGOW_HASKELL__ >= 800 )
@@ -15,12 +15,12 @@
 ( error
 ) where
 
-import GHC.Prim
 import Data.Text (Text, unpack)
 
 #if MIN_VERSION_base(4,9,0)
 -- Full stack trace.
 
+import GHC.Prim (TYPE, raise#)
 import GHC.Types (RuntimeRep)
 import Protolude.CallStack (HasCallStack)
 import GHC.Exception (errorCallWithCallStackException)
@@ -32,6 +32,7 @@
 #elif MIN_VERSION_base(4,7,0)
 -- Basic Call Stack with callsite.
 
+import GHC.Prim (raise#)
 import GHC.Exception (errorCallException)
 
 {-# WARNING error "'error' remains in code" #-}
diff --git a/src/Protolude/Exceptions.hs b/src/Protolude/Exceptions.hs
--- a/src/Protolude/Exceptions.hs
+++ b/src/Protolude/Exceptions.hs
@@ -12,11 +12,11 @@
 import Data.Function ((.))
 import Control.Monad.Trans (liftIO)
 import Control.Monad.IO.Class (MonadIO)
-import Control.Monad.Except (ExceptT(..), MonadError, throwError)
+import Control.Monad.Except (ExceptT(ExceptT), MonadError, throwError)
 import Control.Exception as Exception
 import Control.Applicative
 import Data.Maybe (Maybe, maybe)
-import Data.Either (Either(..))
+import Data.Either (Either(Left,Right))
 
 hush :: Alternative m => Either e a -> m a
 hush (Left _)  = empty
diff --git a/src/Protolude/Functor.hs b/src/Protolude/Functor.hs
--- a/src/Protolude/Functor.hs
+++ b/src/Protolude/Functor.hs
@@ -3,8 +3,9 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 
 module Protolude.Functor (
-  Functor(..),
+  Functor(fmap),
   ($>),
+  (<$),
   (<$>),
   (<<$>>),
   (<&>),
@@ -12,23 +13,23 @@
   foreach,
 ) where
 
-import Data.Function ((.))
-import Data.Function (flip)
-
+import Data.Function ((.), flip)
 #if MIN_VERSION_base(4,11,0)
 import Data.Functor ((<&>))
 #endif
 
 #if MIN_VERSION_base(4,7,0)
 import Data.Functor (
-    Functor(..)
+    Functor(fmap)
+  , (<$)
   , ($>)
   , (<$>)
   , void
   )
 #else
 import Data.Functor (
-    Functor(..)
+    Functor(fmap)
+  , (<$)
   , (<$>)
   )
 
diff --git a/src/Protolude/List.hs b/src/Protolude/List.hs
--- a/src/Protolude/List.hs
+++ b/src/Protolude/List.hs
@@ -1,25 +1,26 @@
-{-# LANGUAGE Safe #-}
 {-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE Safe #-}
 
-module Protolude.List (
-  head,
-  ordNub,
-  sortOn,
-  list,
-  product,
-  sum,
-  groupBy,
-) where
+module Protolude.List
+  ( head,
+    ordNub,
+    sortOn,
+    list,
+    product,
+    sum,
+    groupBy,
+  )
+where
 
-import Data.List (sortBy, groupBy)
-import Data.Maybe (Maybe(..))
-import Data.Ord (Ord, comparing)
-import Data.Foldable (Foldable, foldr, foldl')
+import Control.Applicative (pure)
+import Data.Foldable (Foldable, foldl', foldr)
 import Data.Function ((.))
 import Data.Functor (fmap)
-import Control.Applicative (pure)
+import Data.List (groupBy, sortBy)
+import Data.Maybe (Maybe (Nothing))
+import Data.Ord (Ord, comparing)
 import qualified Data.Set as Set
-import GHC.Num (Num, (+), (*))
+import GHC.Num ((*), (+), Num)
 
 head :: (Foldable f) => f a -> Maybe a
 head = foldr (\x _ -> pure x) Nothing
@@ -31,16 +32,16 @@
 ordNub :: (Ord a) => [a] -> [a]
 ordNub l = go Set.empty l
   where
-    go _ []     = []
-    go s (x:xs) =
+    go _ [] = []
+    go s (x : xs) =
       if x `Set.member` s
-      then go s xs
-      else x : go (Set.insert x s) xs
+        then go s xs
+        else x : go (Set.insert x s) xs
 
 list :: [b] -> (a -> b) -> [a] -> [b]
 list def f xs = case xs of
   [] -> def
-  _  -> fmap f xs
+  _ -> fmap f xs
 
 {-# INLINE product #-}
 product :: (Foldable f, Num a) => f a -> a
diff --git a/src/Protolude/Monad.hs b/src/Protolude/Monad.hs
--- a/src/Protolude/Monad.hs
+++ b/src/Protolude/Monad.hs
@@ -4,7 +4,7 @@
 
 module Protolude.Monad (
     Monad((>>=), return)
-  , MonadPlus(..)
+  , MonadPlus(mzero, mplus)
 
   , (=<<)
   , (>=>)
diff --git a/src/Protolude/Panic.hs b/src/Protolude/Panic.hs
--- a/src/Protolude/Panic.hs
+++ b/src/Protolude/Panic.hs
@@ -7,7 +7,7 @@
 #endif
 
 module Protolude.Panic (
-  FatalError(..),
+  FatalError(FatalError, fatalErrorMessage),
   panic,
 ) where
 
@@ -18,7 +18,7 @@
 import Control.Exception as X
 
 -- | Uncatchable exceptions thrown and never caught.
-data FatalError = FatalError { fatalErrorMessage :: Text }
+newtype FatalError = FatalError { fatalErrorMessage :: Text }
   deriving (Show, Typeable)
 
 instance Exception FatalError
diff --git a/src/Protolude/Partial.hs b/src/Protolude/Partial.hs
new file mode 100644
--- /dev/null
+++ b/src/Protolude/Partial.hs
@@ -0,0 +1,26 @@
+module Protolude.Partial
+  ( head,
+    init,
+    tail,
+    last,
+    foldl,
+    foldr,
+    foldl',
+    foldr',
+    foldr1,
+    foldl1,
+    cycle,
+    maximum,
+    minimum,
+    (!!),
+    sum,
+    product,
+    fromJust,
+    read,
+  )
+where
+
+import Data.Foldable (foldl, foldl', foldl1, foldr, foldr', foldr1, product, sum)
+import Data.List ((!!), cycle, head, init, last, maximum, minimum, tail)
+import Data.Maybe (fromJust)
+import Text.Read (read)
diff --git a/src/Protolude/Safe.hs b/src/Protolude/Safe.hs
--- a/src/Protolude/Safe.hs
+++ b/src/Protolude/Safe.hs
@@ -26,12 +26,12 @@
 ) where
 
 
-import Data.Ord (Ord(..))
+import Data.Ord (Ord, (<))
 import Data.Int (Int)
 import Data.Char (Char)
 import Data.Bool (Bool, otherwise)
-import Data.Maybe (Maybe(..), fromMaybe)
-import Data.Either (Either(..))
+import Data.Maybe (Maybe(Nothing, Just), fromMaybe)
+import Data.Either (Either(Left, Right))
 import Data.Function ((.))
 import Data.List (null, head, last, tail, init, maximum, minimum, foldr1, foldl1, foldl1', (++))
 
diff --git a/src/Protolude/Semiring.hs b/src/Protolude/Semiring.hs
--- a/src/Protolude/Semiring.hs
+++ b/src/Protolude/Semiring.hs
@@ -1,10 +1,13 @@
 {-# LANGUAGE Safe #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 
-module Protolude.Semiring (
-  Semiring(..),
-  zero,
-) where
+module Protolude.Semiring
+  ( Semiring,
+    one,
+    (<.>),
+    zero,
+  )
+where
 
 import Data.Monoid
 
diff --git a/src/Protolude/Show.hs b/src/Protolude/Show.hs
--- a/src/Protolude/Show.hs
+++ b/src/Protolude/Show.hs
@@ -1,35 +1,35 @@
-{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE Trustworthy #-}
 {-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE ExtendedDefaultRules #-}
 
-module Protolude.Show (
-  Print(..),
-  putText,
-  putErrText,
-  putLText,
-  putByteString,
-  putLByteString,
-) where
-
-import qualified System.IO as Base
-import qualified Protolude.Base as Base
-import Data.Function ((.))
+module Protolude.Show
+  ( Print,
+    hPutStr,
+    putStr,
+    hPutStrLn,
+    putStrLn,
+    putErrLn,
+    putText,
+    putErrText,
+    putLText,
+    putByteString,
+    putLByteString,
+  )
+where
 
 import Control.Monad.IO.Class (MonadIO, liftIO)
 import qualified Data.ByteString.Char8 as BS
 import qualified Data.ByteString.Lazy.Char8 as BL
-
+import Data.Function ((.))
 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
-
-import System.IO (Handle, stdout, stderr)
-
+import qualified Protolude.Base as Base
+import qualified System.IO as Base
+import System.IO (Handle, stderr, stdout)
 
 class Print a where
   hPutStr :: MonadIO m => Handle -> a -> m ()
@@ -38,7 +38,7 @@
   hPutStrLn :: MonadIO m => Handle -> a -> m ()
   putStrLn :: MonadIO m => a -> m ()
   putStrLn = hPutStrLn stdout
-  putErrLn ::  MonadIO m => a -> m ()
+  putErrLn :: MonadIO m => a -> m ()
   putErrLn = hPutStrLn stderr
 
 instance Print T.Text where
diff --git a/src/Protolude/Unsafe.hs b/src/Protolude/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/src/Protolude/Unsafe.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE Unsafe #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Protolude.Unsafe (
+  unsafeHead,
+  unsafeTail,
+  unsafeInit,
+  unsafeLast,
+  unsafeFromJust,
+  unsafeIndex,
+  unsafeThrow,
+  unsafeRead,
+) where
+
+import Protolude.Base (Int)
+import Data.Char (Char)
+import Text.Read (Read, read)
+import qualified Data.List as List
+import qualified Data.Maybe as Maybe
+import qualified Control.Exception as Exc
+
+unsafeHead :: [a] -> a
+unsafeHead = List.head
+
+unsafeTail :: [a] -> [a]
+unsafeTail = List.tail
+
+unsafeInit :: [a] -> [a]
+unsafeInit = List.init
+
+unsafeLast :: [a] -> a
+unsafeLast = List.last
+
+unsafeFromJust :: Maybe.Maybe a -> a
+unsafeFromJust = Maybe.fromJust
+
+unsafeIndex :: [a] -> Int -> a
+unsafeIndex = (List.!!)
+
+unsafeThrow :: Exc.Exception e => e -> a
+unsafeThrow = Exc.throw
+
+unsafeRead :: Read a => [Char] -> a
+unsafeRead = Text.Read.read
diff --git a/src/Unsafe.hs b/src/Unsafe.hs
deleted file mode 100644
--- a/src/Unsafe.hs
+++ /dev/null
@@ -1,38 +0,0 @@
-{-# LANGUAGE Unsafe #-}
-{-# LANGUAGE NoImplicitPrelude #-}
-
-module Unsafe (
-  unsafeHead,
-  unsafeTail,
-  unsafeInit,
-  unsafeLast,
-  unsafeFromJust,
-  unsafeIndex,
-  unsafeThrow,
-) where
-
-import Protolude.Base (Int)
-import qualified Data.List as List
-import qualified Data.Maybe as Maybe
-import qualified Control.Exception as Exc
-
-unsafeHead :: [a] -> a
-unsafeHead = List.head
-
-unsafeTail :: [a] -> [a]
-unsafeTail = List.tail
-
-unsafeInit :: [a] -> [a]
-unsafeInit = List.init
-
-unsafeLast :: [a] -> a
-unsafeLast = List.last
-
-unsafeFromJust :: Maybe.Maybe a -> a
-unsafeFromJust = Maybe.fromJust
-
-unsafeIndex :: [a] -> Int -> a
-unsafeIndex = (List.!!)
-
-unsafeThrow :: Exc.Exception e => e -> a
-unsafeThrow = Exc.throw
