{-# LANGUAGE CPP #-}
{-# LANGUAGE UndecidableInstances #-}
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ <= 708
{-# LANGUAGE OverlappingInstances #-}
#endif
module Language.Syntactic.Sugar where
import Language.Syntactic.Syntax
import Language.Syntactic.Constraint
class Syntactic a
where
type Domain a :: * -> *
type Internal a
desugar :: a -> ASTF (Domain a) (Internal a)
sugar :: ASTF (Domain a) (Internal a) -> a
instance Syntactic (ASTF dom a)
where
{-# SPECIALIZE instance Syntactic (ASTF dom a) #-}
type Domain (ASTF dom a) = dom
type Internal (ASTF dom a) = a
desugar = id
sugar = id
{-# INLINABLE desugar #-}
{-# INLINABLE sugar #-}
resugar :: (Syntactic a, Syntactic b, Domain a ~ Domain b, Internal a ~ Internal b) => a -> b
resugar = sugar . desugar
{-# INLINABLE resugar #-}
class SyntacticN a internal | a -> internal
where
desugarN :: a -> internal
sugarN :: internal -> a
instance {-# OVERLAPPABLE #-}
(Syntactic a, Domain a ~ dom, ia ~ AST dom (Full (Internal a))) => SyntacticN a ia
where
{-# SPECIALIZE instance ( Syntactic a, Domain a ~ dom
, ia ~ AST dom (Full (Internal a))
) => SyntacticN a ia #-}
desugarN = desugar
sugarN = sugar
{-# INLINABLE desugarN #-}
{-# INLINABLE sugarN #-}
instance {-# OVERLAPPABLE #-}
( Syntactic a
, Domain a ~ dom
, ia ~ Internal a
, SyntacticN b ib
) =>
SyntacticN (a -> b) (AST dom (Full ia) -> ib)
where
{-# SPECIALIZE instance ( Syntactic a
, Domain a ~ dom
, ia ~ Internal a
, SyntacticN b ib
) => SyntacticN (a -> b) (AST dom (Full ia) -> ib) #-}
desugarN f = desugarN . f . sugar
sugarN f = sugarN . f . desugar
{-# INLINABLE desugarN #-}
{-# INLINABLE sugarN #-}
sugarSym :: (sym :<: AST dom, ApplySym sig b dom, SyntacticN c b) =>
sym sig -> c
sugarSym = sugarN . appSym
{-# INLINABLE sugarSym #-}
sugarSymC
:: ( InjectC sym (AST dom) (DenResult sig)
, ApplySym sig b dom
, SyntacticN c b
)
=> sym sig -> c
sugarSymC = sugarN . appSymC
{-# INLINABLE sugarSymC #-}