@@ -110,7 +110,8 @@ type family IsSubList a b :: Constraint where
110 IsSubList '[] b = ()
110 IsSubList '[] b = ()
111 IsSubList (x ': xs) y = Elem x y `And` IsSubList xs y
111 IsSubList (x ': xs) y = Elem x y `And` IsSubList xs y
113+#if !MIN_VERSION_base(4,9,0)
113−-- | Check that an eleme is an element of a list:
114+-- | Check that a value is an element of a list:
115-- >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
116-- >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
@@ -121,13 +122,31 @@ type family IsSubList a b :: Constraint where
121-- arising from a use of ‘ok’
122-- arising from a use of ‘ok’
123type Elem e es = ElemGo e es es
124type Elem e es = ElemGo e es es
126+-- | Check that a value is an element of a list:
128+-- >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
131+-- >>> ok (Proxy :: Proxy (Elem String '[Int, Bool]))
133+-- ... [Char] expected in list '[Int, Bool]
135+type Elem e es = ElemGo e es es
125-- 'orig' is used to store original list for better error messages
138-- 'orig' is used to store original list for better error messages
126type family ElemGo e es orig :: Constraint where
139type family ElemGo e es orig :: Constraint where
127 ElemGo x (x ': xs) orig = ()
140 ElemGo x (x ': xs) orig = ()
128 ElemGo y (x ': xs) orig = ElemGo y xs orig
141 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)
129 ElemGo x '[] orig = ElemNotFoundIn x orig
148 ElemGo x '[] orig = ElemNotFoundIn x orig
132-- ** Logic
151-- ** Logic
@@ -144,30 +163,16 @@ type family And (a :: Constraint) (b :: Constraint) :: Constraint where
145-- * Custom type errors
164-- * Custom type errors
147−#if MIN_VERSION_base(4,9,0)
166+#if !MIN_VERSION_base(4,9,0)
151−type ElemNotFoundIn val list = TypeError
152− (ShowType val :<>: Text " expected in list " :<>: ShowList list)
157−type family ShowListGo ls :: ErrorMessage where
158− ShowListGo '[] = Text ""
159− ShowListGo (x ': xs) = ShowType x :<>: Text ", " :<>: ShowListGo xs
161−type ShowList ls = Text "[" :<>: ShowListGo ls :<>: Text "]"
167class ElemNotFoundIn val list
167class ElemNotFoundIn val list
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).
172-- >>> import Data.Proxy
177-- >>> import Data.Proxy
173-- >>> data OK = OK deriving (Show)
178-- >>> data OK = OK deriving (Show)