hermit-0.2.0.0: src/Language/HERMIT/Kure/SumTypes.hs
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeSynonymInstances, InstanceSigs #-}
module Language.HERMIT.Kure.SumTypes
( -- * Sum Types
Core(..)
, TyCo(..)
, CoreTC(..)
)
where
import GhcPlugins
import Language.KURE.Injection
import Language.HERMIT.Core
---------------------------------------------------------------------
-- | Core is a sum type for use by KURE. Core = ModGuts + CoreProg + CoreBind + CoreDef + CoreExpr + CoreAlt
data Core = GutsCore ModGuts -- ^ The module.
| ProgCore CoreProg -- ^ A program (a telescope of top-level binding groups).
| BindCore CoreBind -- ^ A binding group.
| DefCore CoreDef -- ^ A recursive definition.
| ExprCore CoreExpr -- ^ An expression.
| AltCore CoreAlt -- ^ A case alternative.
-- | TyCo is a sum type for use by KURE. TyCo = Type + Coercion
data TyCo = TypeCore Type -- ^ A type.
| CoercionCore Coercion -- ^ A coercion.
-- | CoreTC is a sum type for use by KURE. CoreTC = Core + TyCo
data CoreTC = Core Core
| TyCo TyCo
---------------------------------------------------------------------
instance Injection ModGuts Core where
inject :: ModGuts -> Core
inject = GutsCore
{-# INLINE inject #-}
project :: Core -> Maybe ModGuts
project (GutsCore guts) = Just guts
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreProg Core where
inject :: CoreProg -> Core
inject = ProgCore
{-# INLINE inject #-}
project :: Core -> Maybe CoreProg
project (ProgCore bds) = Just bds
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreBind Core where
inject :: CoreBind -> Core
inject = BindCore
{-# INLINE inject #-}
project :: Core -> Maybe CoreBind
project (BindCore bnd) = Just bnd
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreDef Core where
inject :: CoreDef -> Core
inject = DefCore
{-# INLINE inject #-}
project :: Core -> Maybe CoreDef
project (DefCore def) = Just def
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreAlt Core where
inject :: CoreAlt -> Core
inject = AltCore
{-# INLINE inject #-}
project :: Core -> Maybe CoreAlt
project (AltCore expr) = Just expr
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreExpr Core where
inject :: CoreExpr -> Core
inject = ExprCore
{-# INLINE inject #-}
project :: Core -> Maybe CoreExpr
project (ExprCore expr) = Just expr
project _ = Nothing
{-# INLINE project #-}
---------------------------------------------------------------------
instance Injection Type TyCo where
inject :: Type -> TyCo
inject = TypeCore
{-# INLINE inject #-}
project :: TyCo -> Maybe Type
project (TypeCore ty) = Just ty
project _ = Nothing
{-# INLINE project #-}
instance Injection Coercion TyCo where
inject :: Coercion -> TyCo
inject = CoercionCore
{-# INLINE inject #-}
project :: TyCo -> Maybe Coercion
project (CoercionCore ty) = Just ty
project _ = Nothing
{-# INLINE project #-}
---------------------------------------------------------------------
instance Injection Core CoreTC where
inject :: Core -> CoreTC
inject = Core
{-# INLINE inject #-}
project :: CoreTC -> Maybe Core
project (Core core) = Just core
project _ = Nothing
{-# INLINE project #-}
instance Injection TyCo CoreTC where
inject :: TyCo -> CoreTC
inject = TyCo
{-# INLINE inject #-}
project :: CoreTC -> Maybe TyCo
project (TyCo tyCo) = Just tyCo
project _ = Nothing
{-# INLINE project #-}
---------------------------------------------------------------------
instance Injection ModGuts CoreTC where
inject :: ModGuts -> CoreTC
inject = Core . GutsCore
{-# INLINE inject #-}
project :: CoreTC -> Maybe ModGuts
project (Core (GutsCore guts)) = Just guts
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreProg CoreTC where
inject :: CoreProg -> CoreTC
inject = Core . ProgCore
{-# INLINE inject #-}
project :: CoreTC -> Maybe CoreProg
project (Core (ProgCore bds)) = Just bds
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreBind CoreTC where
inject :: CoreBind -> CoreTC
inject = Core . BindCore
{-# INLINE inject #-}
project :: CoreTC -> Maybe CoreBind
project (Core (BindCore bnd)) = Just bnd
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreDef CoreTC where
inject :: CoreDef -> CoreTC
inject = Core . DefCore
{-# INLINE inject #-}
project :: CoreTC -> Maybe CoreDef
project (Core (DefCore def)) = Just def
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreAlt CoreTC where
inject :: CoreAlt -> CoreTC
inject = Core . AltCore
{-# INLINE inject #-}
project :: CoreTC -> Maybe CoreAlt
project (Core (AltCore expr)) = Just expr
project _ = Nothing
{-# INLINE project #-}
instance Injection CoreExpr CoreTC where
inject :: CoreExpr -> CoreTC
inject = Core . ExprCore
{-# INLINE inject #-}
project :: CoreTC -> Maybe CoreExpr
project (Core (ExprCore expr)) = Just expr
project _ = Nothing
{-# INLINE project #-}
instance Injection Type CoreTC where
inject :: Type -> CoreTC
inject = TyCo . TypeCore
{-# INLINE inject #-}
project :: CoreTC -> Maybe Type
project (TyCo (TypeCore ty)) = Just ty
project _ = Nothing
{-# INLINE project #-}
instance Injection Coercion CoreTC where
inject :: Coercion -> CoreTC
inject = TyCo . CoercionCore
{-# INLINE inject #-}
project :: CoreTC -> Maybe Coercion
project (TyCo (CoercionCore ty)) = Just ty
project _ = Nothing
{-# INLINE project #-}
---------------------------------------------------------------------