{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Type.Error
( ErrorIfAmbiguous
, ListBulletsWith
, MessageIfNonEmpty
, ThrowMessagesWithHeader
, UnlinesMessages
)
where
import Data.Kind
( Constraint )
import GHC.TypeLits
( TypeError, ErrorMessage(..) )
import Data.Generics.Product.Internal.GLens
( Eval, TyFun )
type ErrorIfAmbiguous :: k -> Constraint -> l -> l
type family ErrorIfAmbiguous break err a where
ErrorIfAmbiguous Dummy _ _ = Dummy
ErrorIfAmbiguous _ _ a = a
type Dummy :: k
data family Dummy
type MessageIfNonEmpty :: TyFun ty ErrorMessage -> [ ty ] -> ErrorMessage -> Maybe ErrorMessage
type family MessageIfNonEmpty showTySym tys message where
MessageIfNonEmpty _ '[] _ = Nothing
MessageIfNonEmpty showTySym tys message = Just ( message :$$: ListBulletsWith showTySym tys )
type ListBulletsWith :: TyFun ty ErrorMessage -> [ ty ] -> ErrorMessage
type family ListBulletsWith showTySym tys where
ListBulletsWith _ '[] = Text ""
ListBulletsWith showTySym ( ty ': tys ) = Text " - " :<>: Eval showTySym ty
:$$: ListBulletsWith showTySym tys
type ThrowMessagesWithHeader :: ErrorMessage -> [ ErrorMessage ] -> Constraint
type family header messages where
_ '[] = ( () :: Constraint )
header messages = TypeError ( header :$$: UnlinesMessages messages )
type UnlinesMessages :: [ ErrorMessage ] -> ErrorMessage
type family UnlinesMessages messages where
UnlinesMessages '[] = Text ""
UnlinesMessages ( m ': ms ) = m :$$: UnlinesMessages ms