diff --git a/Inj/Base.hs b/Inj/Base.hs
--- a/Inj/Base.hs
+++ b/Inj/Base.hs
@@ -2,7 +2,7 @@
 
 {-# LANGUAGE
     DefaultSignatures,
-    MultiParamTypeClasses,
+    FunctionalDependencies,
     FlexibleInstances,
     FlexibleContexts,
     TypeFamilies,
@@ -14,10 +14,10 @@
 
 module Inj.Base () where
 
-import GHC.TypeLits
 import Control.Applicative
 import Control.Exception hiding (TypeError)
 import Control.Monad.ST
+import Data.Bifunctor
 import Data.Complex
 import Data.Fixed
 import Data.Functor.Compose
@@ -40,6 +40,125 @@
 import Inj
 
 --------------------------------------------------------------------------------
+-- Identity injections
+--------------------------------------------------------------------------------
+
+instance p ~ () => Inj p ()
+instance p ~ Bool => Inj p Bool
+instance p ~ Ordering => Inj p Ordering
+
+instance p ~ Proxy t' => Inj p (Proxy t) where
+  inj Proxy = Proxy
+
+--------------------------------------------------------------------------------
+-- Decision procedures for ambiguous injections
+--------------------------------------------------------------------------------
+
+data Decision_Wrap
+
+data Decision_Map
+
+type family DecideMaybe p where
+  DecideMaybe (Maybe p) = Decision_Map
+  DecideMaybe p = Decision_Wrap
+
+class d ~ DecideMaybe p => InjMaybe d p a where
+  injMaybe :: p -> Maybe a
+
+instance InjMaybe (DecideMaybe p) p a => Inj p (Maybe a) where
+  inj = injMaybe
+
+type family DecideList p where
+  DecideList [p] = Decision_Map
+  DecideList p = Decision_Wrap
+
+class d ~ DecideList p => InjList d p a where
+  injList :: p -> [a]
+
+instance InjList (DecideList p) p a => Inj p [a] where
+  inj = injList
+
+type family DecideNonEmpty p where
+  DecideNonEmpty (NonEmpty p) = Decision_Map
+  DecideNonEmpty p = Decision_Wrap
+
+class d ~ DecideNonEmpty p => InjNonEmpty d p a where
+  injNonEmpty :: p -> NonEmpty a
+
+instance InjNonEmpty (DecideNonEmpty p) p a => Inj p (NonEmpty a) where
+  inj = injNonEmpty
+
+type family DecideIO p where
+  DecideIO (IO p) = Decision_Map
+  DecideIO p = Decision_Wrap
+
+class d ~ DecideIO p => InjIO d p a where
+  injIO :: p -> IO a
+
+instance InjIO (DecideIO p) p a => Inj p (IO a) where
+  inj = injIO
+
+type family DecideSTM p where
+  DecideSTM (STM p) = Decision_Map
+  DecideSTM p = Decision_Wrap
+
+class d ~ DecideSTM p => InjSTM d p a where
+  injSTM :: p -> STM a
+
+instance InjSTM (DecideSTM p) p a => Inj p (STM a) where
+  inj = injSTM
+
+type family DecideIdentity p where
+  DecideIdentity (Identity p) = Decision_Map
+  DecideIdentity p = Decision_Wrap
+
+class d ~ DecideIdentity p => InjIdentity d p a where
+  injIdentity :: p -> Identity a
+
+instance InjIdentity (DecideIdentity p) p a => Inj p (Identity a) where
+  inj = injIdentity
+
+type family DecideZipList p where
+  DecideZipList (ZipList p) = Decision_Map
+  DecideZipList p = Decision_Wrap
+
+class d ~ DecideZipList p => InjZipList d p a where
+  injZipList :: p -> ZipList a
+
+instance InjZipList (DecideZipList p) p a => Inj p (ZipList a) where
+  inj = injZipList
+
+type family DecideOption p where
+  DecideOption (Option p) = Decision_Map
+  DecideOption p = Decision_Wrap
+
+class d ~ DecideOption p => InjOption d p a where
+  injOption :: p -> Option a
+
+instance InjOption (DecideOption p) p a => Inj p (Option a) where
+  inj = injOption
+
+type family DecideST p where
+  DecideST (ST s p) = Decision_Map
+  DecideST p = Decision_Wrap
+
+class d ~ DecideST p => InjST d p s a where
+  injST :: p -> ST s a
+
+instance InjST (DecideST p) p s a => Inj p (ST s a) where
+  inj = injST
+
+type family DecideFn p where
+  DecideFn (r -> p) = Decision_Map
+  DecideFn p = Decision_Wrap
+
+class d ~ DecideFn p => InjFn d p r a where
+  injFn :: p -> r -> a
+
+instance InjFn (DecideFn p) p r a => Inj p (r -> a) where
+  inj = injFn
+
+--------------------------------------------------------------------------------
 -- 'fromIntegral' is an injection from any @Integral p@ to any @Num a@.
 --------------------------------------------------------------------------------
 
@@ -140,17 +259,29 @@
 -- 'pure' is often an injection into @Applicative f@.
 --------------------------------------------------------------------------------
 
-instance Inj p a => Inj p [a] where
-  inj = pure . inj
+instance
+    (DecideList p ~ Decision_Wrap, Inj p a) =>
+    InjList Decision_Wrap p a
+  where
+    injList = pure . inj
 
-instance Inj p a => Inj p (Maybe a) where
-  inj = pure . inj
+instance
+    (DecideMaybe p ~ Decision_Wrap, Inj p a) =>
+    InjMaybe Decision_Wrap p a
+  where
+    injMaybe = pure . inj
 
-instance Inj p a => Inj p (IO a) where
-  inj = pure . inj
+instance
+    (DecideNonEmpty p ~ Decision_Wrap, Inj p a) =>
+    InjNonEmpty Decision_Wrap p a
+  where
+    injNonEmpty = pure . inj
 
-instance Inj p a => Inj p (NonEmpty a) where
-  inj = pure . inj
+instance
+    (DecideIO p ~ Decision_Wrap, Inj p a) =>
+    InjIO Decision_Wrap p a
+  where
+    injIO = pure . inj
 
 instance Inj p a => Inj p (ReadP a) where
   inj = pure . inj
@@ -176,17 +307,29 @@
 instance Inj p a => Inj p (Data.Monoid.First a) where
   inj = pure . inj
 
-instance Inj p a => Inj p (STM a) where
-  inj = pure . inj
+instance
+    (DecideSTM p ~ Decision_Wrap, Inj p a) =>
+    InjSTM Decision_Wrap p a
+  where
+    injSTM = pure . inj
 
-instance Inj p a => Inj p (Identity a) where
-  inj = pure . inj
+instance
+    (DecideIdentity p ~ Decision_Wrap, Inj p a) =>
+    InjIdentity Decision_Wrap p a
+  where
+    injIdentity = pure . inj
 
-instance Inj p a => Inj p (ZipList a) where
-  inj = pure . inj
+instance
+    (DecideZipList p ~ Decision_Wrap, Inj p a) =>
+    InjZipList Decision_Wrap p a
+  where
+    injZipList = pure . inj
 
-instance Inj p a => Inj p (Option a) where
-  inj = pure . inj
+instance
+    (DecideOption p ~ Decision_Wrap, Inj p a) =>
+    InjOption Decision_Wrap p a
+  where
+    injOption = pure . inj
 
 instance Inj p a => Inj p (Data.Semigroup.Last a) where
   inj = pure . inj
@@ -201,35 +344,104 @@
   inj = pure . inj
 
 instance
-    TypeError
-      ('Text "Refusing to decide whether to inject " ':<>:
-       'ShowType p ':<>: 'Text " into 'Left' " ':<>:
-       'ShowType x ':<>: 'Text " or 'Right' " ':<>: 'ShowType y ':$$:
-       'Text "in the " ':<>: 'ShowType Inj ':<>:
-       'Text " instance for " ':<>: 'ShowType Either) =>
-    Inj p (Either x y)
+    (DecideST p ~ Decision_Wrap, Inj p a) =>
+    InjST Decision_Wrap p s a
   where
-    inj = error "impossible"
+    injST = pure . inj
 
 instance
-    TypeError
-      ('Text "Refusing to decide whether to inject " ':<>:
-       'ShowType p ':<>: 'Text " into 'fst' " ':<>:
-       'ShowType x ':<>: 'Text " or 'snd' " ':<>: 'ShowType y ':$$:
-       'Text "in the " ':<>: 'ShowType Inj ':<>:
-       'Text " instance for " ':<>: 'ShowType (,)) =>
-    Inj p ((,) x y)
+    (DecideFn p ~ Decision_Wrap, Inj p a) =>
+    InjFn Decision_Wrap p s a
   where
-    inj = error "impossible"
-
-instance Inj p a => Inj p (ST s a) where
-  inj = pure . inj
-
-instance Inj p a => Inj p (r -> a) where
-  inj = pure . inj
+    injFn = pure . inj
 
 instance Inj p (f (g a)) => Inj p (Compose f g a) where
   inj = Compose . inj
+
+--------------------------------------------------------------------------------
+-- 'fmap', 'bimap', etc, can be used to map injections
+--------------------------------------------------------------------------------
+
+instance
+    (DecideMaybe p ~ Decision_Map, p ~ Maybe p', Inj p' a) =>
+    InjMaybe Decision_Map p a
+  where
+    injMaybe = fmap inj
+
+instance
+    (DecideList p ~ Decision_Map, p ~ [p'], Inj p' a) =>
+    InjList Decision_Map p a
+  where
+    injList = fmap inj
+
+instance
+    (DecideNonEmpty p ~ Decision_Map, p ~ NonEmpty p', Inj p' a) =>
+    InjNonEmpty Decision_Map p a
+  where
+    injNonEmpty = fmap inj
+
+instance
+    (DecideIO p ~ Decision_Map, p ~ IO p', Inj p' a) =>
+    InjIO Decision_Map p a
+  where
+    injIO = fmap inj
+
+instance
+    (DecideSTM p ~ Decision_Map, p ~ STM p', Inj p' a) =>
+    InjSTM Decision_Map p a
+  where
+    injSTM = fmap inj
+
+instance
+    (DecideIdentity p ~ Decision_Map, p ~ Identity p', Inj p' a) =>
+    InjIdentity Decision_Map p a
+  where
+    injIdentity = fmap inj
+
+instance
+    (DecideZipList p ~ Decision_Map, p ~ ZipList p', Inj p' a) =>
+    InjZipList Decision_Map p a
+  where
+    injZipList = fmap inj
+
+instance
+    (DecideOption p ~ Decision_Map, p ~ Option p', Inj p' a) =>
+    InjOption Decision_Map p a
+  where
+    injOption = fmap inj
+
+instance
+    (DecideST p ~ Decision_Map, p ~ ST s p', Inj p' a) =>
+    InjST Decision_Map p s a
+  where
+    injST = fmap inj
+
+instance
+    (DecideFn p ~ Decision_Map, p ~ (r -> p'), Inj p' a) =>
+    InjFn Decision_Map p r a
+  where
+    injFn = fmap inj
+
+instance (t ~ (pa, pb), Inj pa a, Inj pb b) => Inj t (a, b) where
+  inj = bimap inj inj
+
+instance
+    (t ~ (pa, pb, pc), Inj pa a, Inj pb b, Inj pc c) =>
+    Inj t (a, b, c)
+  where
+    inj (pa, pb, pc) = (inj pa, inj pb, inj pc)
+
+instance
+    (t ~ (pa, pb, pc, pd), Inj pa a, Inj pb b, Inj pc c, Inj pd d) =>
+    Inj t (a, b, c, d)
+  where
+    inj (pa, pb, pc, pd) = (inj pa, inj pb, inj pc, inj pd)
+
+instance (t ~ Either pa pb, Inj pa a, Inj pb b) => Inj t (Either a b) where
+  inj = bimap inj inj
+
+instance (t ~ Const pa pb, Inj pa a) => Inj t (Const a b) where
+  inj (Const pa) = Const (inj pa)
 
 --------------------------------------------------------------------------------
 -- Generic
diff --git a/inj-base.cabal b/inj-base.cabal
--- a/inj-base.cabal
+++ b/inj-base.cabal
@@ -1,5 +1,5 @@
 name:                inj-base
-version:             0.1.0.0
+version:             0.2.0.0
 synopsis:            'Inj' instances for 'base'
 license:             BSD3
 license-file:        LICENSE
