Skip to content

Commit 02e4281

Browse files
jkarniphadej
authored andcommitted
Custom type errors
1 parent 92b1196 commit 02e4281

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

servant/src/Servant/API/TypeLevel.hs

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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
-- ...
123124
type 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
126139
type 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)
167167
class 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)

0 commit comments

Comments
 (0)