Custom type errors

This commit is contained in:
Julian K. Arni 2016-08-22 12:44:39 -03:00 committed by Oleg Grenrus
parent 92b1196830
commit 02e4281d51

View file

@ -110,7 +110,8 @@ type family IsSubList a b :: Constraint where
IsSubList '[] b = () IsSubList '[] b = ()
IsSubList (x ': xs) y = Elem x y `And` IsSubList xs y IsSubList (x ': xs) y = Elem x y `And` IsSubList xs y
-- | Check that an eleme is an element of a list: #if !MIN_VERSION_base(4,9,0)
-- | Check that a value is an element of a list:
-- --
-- >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool])) -- >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
-- OK -- OK
@ -121,13 +122,31 @@ type family IsSubList a b :: Constraint where
-- arising from a use of ok -- arising from a use of ok
-- ... -- ...
type Elem e es = ElemGo e es es type Elem e es = ElemGo e es es
#else
-- | Check that a value is an element of a list:
--
-- >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
-- OK
--
-- >>> ok (Proxy :: Proxy (Elem String '[Int, Bool]))
-- ...
-- ... [Char] expected in list '[Int, Bool]
-- ...
type Elem e es = ElemGo e es es
#endif
-- 'orig' is used to store original list for better error messages -- 'orig' is used to store original list for better error messages
type family ElemGo e es orig :: Constraint where type family ElemGo e es orig :: Constraint where
ElemGo x (x ': xs) orig = () ElemGo x (x ': xs) orig = ()
ElemGo y (x ': xs) orig = ElemGo y xs orig ElemGo y (x ': xs) orig = ElemGo y xs orig
#if MIN_VERSION_base(4,9,0)
-- Note [Custom Errors]
ElemGo x '[] orig = TypeError ('ShowType x
':<>: 'Text " expected in list "
':<>: 'ShowType orig)
#else
ElemGo x '[] orig = ElemNotFoundIn x orig ElemGo x '[] orig = ElemNotFoundIn x orig
#endif
-- ** Logic -- ** Logic
@ -144,30 +163,16 @@ type family And (a :: Constraint) (b :: Constraint) :: Constraint where
-- * Custom type errors -- * Custom type errors
#if MIN_VERSION_base(4,9,0) #if !MIN_VERSION_base(4,9,0)
-- GHC >= 8
type ElemNotFoundIn val list = TypeError
(ShowType val :<>: Text " expected in list " :<>: ShowList list)
-- Utilities
type family ShowListGo ls :: ErrorMessage where
ShowListGo '[] = Text ""
ShowListGo (x ': xs) = ShowType x :<>: Text ", " :<>: ShowListGo xs
type ShowList ls = Text "[" :<>: ShowListGo ls :<>: Text "]"
#else
-- GHC < 8
class ElemNotFoundIn val list class ElemNotFoundIn val list
#endif #endif
{- Note [Custom Errors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We might try to factor these our more cleanly, but the type synonyms and type
families are not evaluated (see https://ghc.haskell.org/trac/ghc/ticket/12048).
-}
-- $setup -- $setup
-- >>> import Data.Proxy -- >>> import Data.Proxy
-- >>> data OK = OK deriving (Show) -- >>> data OK = OK deriving (Show)