diff --git a/shell-conduit.cabal b/shell-conduit.cabal
--- a/shell-conduit.cabal
+++ b/shell-conduit.cabal
@@ -1,5 +1,5 @@
 name:                shell-conduit
-version:             0.1
+version:             1.0
 synopsis:            Write shell scripts with Conduit
 description:         Write shell scripts with Conduit. See "Data.Conduit.Shell" for documentation.
 license:             BSD3
diff --git a/src/Data/Conduit/Shell/PATH.hs b/src/Data/Conduit/Shell/PATH.hs
--- a/src/Data/Conduit/Shell/PATH.hs
+++ b/src/Data/Conduit/Shell/PATH.hs
@@ -1,12 +1,14 @@
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE NoMonomorphismRestriction #-}
 {-# LANGUAGE QuasiQuotes #-}
-{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+{-# OPTIONS_GHC -fno-warn-missing-signatures -fno-warn-unused-imports #-}
 
 -- | All binaries in PATH.
 
 module Data.Conduit.Shell.PATH where
 
 import Data.Conduit.Shell.TH
+import Data.List
+import Control.Monad
 
 $(generateBinaries)
diff --git a/src/Data/Conduit/Shell/Process.hs b/src/Data/Conduit/Shell/Process.hs
--- a/src/Data/Conduit/Shell/Process.hs
+++ b/src/Data/Conduit/Shell/Process.hs
@@ -32,7 +32,6 @@
 import           Data.Conduit.List (sourceList)
 import qualified Data.Conduit.List as CL
 import           Data.Conduit.Process
-import           Data.Either
 import           System.Exit (ExitCode(..))
 import           System.IO
 import qualified System.Process
@@ -121,6 +120,7 @@
              hClose cerr
              _ <- waitForProcess' ph
              return ()
+        closep _ = error "conduitProcess: unexpected arguments to closep"
 
 -- | Start proxying from conduit to process back to conduit.
 startProxy :: (MonadIO m,MonadThrow m)
@@ -154,6 +154,7 @@
                                liftIO (do S.hPut cin bytes
                                           hFlush cin)
                            proxyInterleaved
+startProxy _ = error "startProxy: unexpected arguments"
 
 -- | Proxy live results from the given handle and yield them.
 proxy :: MonadIO m
@@ -188,3 +189,8 @@
   E.catch (waitForProcess ph)
           (\(E.SomeException _) ->
              return ExitSuccess)
+
+-- | Polyfill for base < 4.7
+isLeft :: Either a b -> Bool
+isLeft (Left _) = True
+isLeft _        = False
diff --git a/src/Data/Conduit/Shell/TH.hs b/src/Data/Conduit/Shell/TH.hs
--- a/src/Data/Conduit/Shell/TH.hs
+++ b/src/Data/Conduit/Shell/TH.hs
@@ -24,16 +24,17 @@
 generateBinaries :: Q [Dec]
 generateBinaries =
   do bins <- runIO getAllBinaries
-     return (map (\(name,bin) ->
-                    FunD (mkName name)
-                         [Clause []
-                                 (NormalB (AppE (VarE 'variadicProcess)
-                                                (LitE (StringL bin))))
-                                 []])
-                 (nubBy (on (==) fst)
-                        (filter (not . null . fst)
-                                (map (normalize &&& id) bins))))
-  where normalize = remap . uncapitalize . go
+     mapM (\(name,bin) ->
+             do uniqueName <- getUniqueName name
+                return (FunD uniqueName
+                             [Clause []
+                                     (NormalB (AppE (VarE 'variadicProcess)
+                                                    (LitE (StringL bin))))
+                                     []]))
+          (nubBy (on (==) fst)
+                 (filter (not . null . fst)
+                         (map (normalize &&& id) bins)))
+  where normalize = uncapitalize . go
           where go (c:cs)
                   | c == '-' || c == '_' =
                     case go cs of
@@ -50,28 +51,15 @@
           ['a' .. 'z'] ++
           ['0' .. '9']
 
--- | Remap conflicting names.
-remap :: [Char] -> [Char]
-remap name =
-  case name of
-   "head" -> "head'"
-   "seq" -> "seq'"
-   "zip" -> "zip'"
-   "print" -> "print'"
-   "id" -> "id'"
-   "unzip" -> "unzip'"
-   "join" -> "join'"
-   "init" -> "init'"
-   "last" -> "last'"
-   "tail" -> "tail'"
-   "find" -> "find'"
-   "sort" -> "sort'"
-   "sum" -> "sum'"
-   "compare" -> "compare'"
-   "truncate" -> "truncate'"
-   "lex" -> "lex'"
-   "env" -> "env'"
-   e -> e
+-- | Get a version of the given name available to be bound.
+getUniqueName :: String -> Q Name
+getUniqueName candidate =
+  do inScope <- recover (do void (reify (mkName candidate))
+                            return True)
+                        (return False)
+     if inScope
+        then getUniqueName (candidate ++ "'")
+        else return (mkName candidate)
 
 -- | Get a list of all binaries in PATH.
 getAllBinaries :: IO [FilePath]
