{-# LANGUAGE KindSignatures #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ExistentialQuantification #-} module Ivory.Language.Effects ( Effects(..) , AllocEffects , ProcEffects , NoEffects , ReturnEff(..) , GetReturn() , ClearReturn() , BreakEff(..) , GetBreaks() , AllowBreak() , ClearBreak() , AllocEff(..) , GetAlloc() , ClearAlloc() ) where -------------------------------------------------------------------------------- -- Effect Context -- | The effect context for 'Ivory' operations. data Effects = Effects ReturnEff BreakEff AllocEff -- | Function return effect. data ReturnEff = forall t. Returns t | NoReturn -- | Loop break effect. data BreakEff = Break | NoBreak -- | Stack allocation effect. data AllocEff = forall s. Scope s | NoAlloc -------------------------------------------------------------------------------- -- Returns -- | Retrieve any 'Return' effect present. type family GetReturn (effs :: Effects) :: ReturnEff type instance GetReturn ('Effects r b a) = r -- | Remove any 'Return' effects present. type family ClearReturn (effs :: Effects) :: Effects type instance ClearReturn ('Effects r b a) = 'Effects 'NoReturn b a -------------------------------------------------------------------------------- -- Breaks -- | Retrieve any 'Breaks' effect present. type family GetBreaks (effs :: Effects) :: BreakEff type instance GetBreaks ('Effects r b a) = b -- | Add the 'Break' effect into an effect context. type family AllowBreak (effs :: Effects) :: Effects type instance AllowBreak ('Effects r b a) = 'Effects r 'Break a -- | Remove any 'Break' effect present. type family ClearBreak (effs :: Effects) :: Effects type instance ClearBreak ('Effects r b a) = 'Effects r 'NoBreak a -------------------------------------------------------------------------------- -- Allocs -- | Retrieve the current allocation effect. type family GetAlloc (effs :: Effects) :: AllocEff type instance GetAlloc ('Effects r b a) = a -- | Remove any allocation effect currently present. type family ClearAlloc (effs :: Effects) :: Effects type instance ClearAlloc ('Effects r b a) = 'Effects r b 'NoAlloc -------------------------------------------------------------------------------- -- Helpers type AllocEffects s = 'Effects 'NoReturn 'NoBreak ('Scope s) type ProcEffects s t = 'Effects ('Returns t) 'NoBreak ('Scope s) type NoEffects = 'Effects 'NoReturn 'NoBreak 'NoAlloc --------------------------------------------------------------------------------