{-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} module Language.Symantic.Type.Alt where import Language.Symantic.Type.Root -- * Type 'Type_Alt' -- | Type making an alternative between two types. data Type_Alt curr next (root:: * -> *) h = Type_Alt_Curr (curr root h) | Type_Alt_Next (next root h) -- | Convenient alias. Requires @TypeOperators@. type (:|:) = Type_Alt infixr 5 :|: type instance Root_of_Type (Type_Alt curr next root) = root -- * Type family 'Is_Last_Type' -- | Return whether a given type is the last one in a given type stack. -- -- NOTE: each type parser uses this type family -- when it encounters unsupported syntax: -- to know if it is the last type parser component that will be tried -- (and thus return 'Error_Type_Unsupported') -- or if some other type parser component shall be tried -- (and thus return 'Error_Type_Unsupported_here', -- which is then handled accordingly by the 'Type0_From' instance of 'Type_Alt'). type family Is_Last_Type (ty:: * -> *) (tys:: * -> *) :: Bool where Is_Last_Type ty ty = 'True Is_Last_Type ty (Type_Root tys) = Is_Last_Type ty (tys (Type_Root tys)) Is_Last_Type (ty root) (Type_Alt ty next root) = 'False Is_Last_Type other (Type_Alt curr next root) = Is_Last_Type other (next root) -- * Type 'No_Type' -- | A discarded type. data No_Type (root:: * -> *) h = No_Type (root h) deriving (Eq, Show)