@@ -110,7 +110,8 @@ type family IsSubList a b :: Constraint where
110110 IsSubList '[] b = ()
111111 IsSubList (x ': xs) y = Elem x y `And` IsSubList xs y
112112
113−-- | Check that an eleme is an element of a list:
113+#if !MIN_VERSION_base(4,9,0)
114+-- | Check that a value is an element of a list:
114115--
115116-- >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
116117-- OK
@@ -121,13 +122,31 @@ type family IsSubList a b :: Constraint where
121122-- arising from a use of ‘ok’
122123-- ...
123124type Elem e es = ElemGo e es es
125+#else
126+-- | Check that a value is an element of a list:
127+--
128+-- >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
129+-- OK
130+--
131+-- >>> ok (Proxy :: Proxy (Elem String '[Int, Bool]))
132+-- ...
133+-- ... [Char] expected in list '[Int, Bool]
134+-- ...
135+type Elem e es = ElemGo e es es
136+#endif
124137
125138-- 'orig' is used to store original list for better error messages
126139type family ElemGo e es orig :: Constraint where
127140 ElemGo x (x ': xs) orig = ()
128141 ElemGo y (x ': xs) orig = ElemGo y xs orig
142+#if MIN_VERSION_base(4,9,0)
143+ -- Note [Custom Errors]
144+ ElemGo x '[] orig = TypeError ('ShowType x
145+ ':<>: 'Text " expected in list "
146+ ':<>: 'ShowType orig)
147+#else
129148 ElemGo x '[] orig = ElemNotFoundIn x orig
130−
149+#endif
131150
132151-- ** Logic
133152
@@ -144,30 +163,16 @@ type family And (a :: Constraint) (b :: Constraint) :: Constraint where
144163
145164-- * Custom type errors
146165
147−#if MIN_VERSION_base(4,9,0)
148−-- GHC >= 8
149−
150−
151−type ElemNotFoundIn val list = TypeError
152− (ShowType val :<>: Text " expected in list " :<>: ShowList list)
153−
154−
155−-- Utilities
156−
157−type family ShowListGo ls :: ErrorMessage where
158− ShowListGo '[] = Text ""
159− ShowListGo (x ': xs) = ShowType x :<>: Text ", " :<>: ShowListGo xs
160−
161−type ShowList ls = Text "[" :<>: ShowListGo ls :<>: Text "]"
162−
163−
164−#else
165−
166−-- GHC < 8
166+#if !MIN_VERSION_base(4,9,0)
167167class ElemNotFoundIn val list
168−
169168#endif
170169
170+{- Note [Custom Errors]
171+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
172+We might try to factor these our more cleanly, but the type synonyms and type
173+families are not evaluated (see https://ghc.haskell.org/trac/ghc/ticket/12048).
174+-}
175+
171176-- $setup
172177-- >>> import Data.Proxy
173178-- >>> data OK = OK deriving (Show)