{-# LANGUAGE StandaloneKindSignatures #-} {-# LANGUAGE UndecidableInstances #-} module Data.Type.Error ( ErrorIfAmbiguous , ListBulletsWith , MessageIfNonEmpty , ThrowMessagesWithHeader , UnlinesMessages ) where -- base import Data.Kind ( Constraint ) import GHC.TypeLits ( TypeError, ErrorMessage(..) ) -- generic-lens-core 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 ThrowMessagesWithHeader header messages where ThrowMessagesWithHeader _ '[] = ( () :: Constraint ) ThrowMessagesWithHeader header messages = TypeError ( header :$$: UnlinesMessages messages ) type UnlinesMessages :: [ ErrorMessage ] -> ErrorMessage type family UnlinesMessages messages where UnlinesMessages '[] = Text "" UnlinesMessages ( m ': ms ) = m :$$: UnlinesMessages ms