{-# LANGUAGE CPP #-}
{-# LANGUAGE UndecidableInstances #-}
#ifndef MIN_VERSION_GLASGOW_HASKELL
#define MIN_VERSION_GLASGOW_HASKELL(a,b,c,d) 0
#endif
#if MIN_VERSION_GLASGOW_HASKELL(7,10,0,0)
#else
{-# LANGUAGE OverlappingInstances #-}
#endif
module Language.Syntactic.Sugar where
import Data.Typeable
import Language.Syntactic.Syntax
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 sym a)
where
type Domain (ASTF sym a) = sym
type Internal (ASTF sym a) = a
desugar = id
sugar = id
instance Syntactic (ASTFull sym a)
where
type Domain (ASTFull sym a) = sym
type Internal (ASTFull sym a) = a
desugar = unASTFull
sugar = ASTFull
resugar :: (Syntactic a, Syntactic b, Domain a ~ Domain b, Internal a ~ Internal b) => a -> b
resugar = sugar . desugar
class SyntacticN f internal | f -> internal
where
desugarN :: f -> internal
sugarN :: internal -> f
instance {-# OVERLAPPING #-}
(Syntactic f, Domain f ~ sym, fi ~ AST sym (Full (Internal f))) => SyntacticN f fi
where
desugarN = desugar
sugarN = sugar
instance {-# OVERLAPPING #-}
( Syntactic a
, Domain a ~ sym
, ia ~ Internal a
, SyntacticN f fi
) =>
SyntacticN (a -> f) (AST sym (Full ia) -> fi)
where
desugarN f = desugarN . f . sugar
sugarN f = sugarN . f . desugar
sugarSym
:: ( Signature sig
, fi ~ SmartFun sup sig
, sig ~ SmartSig fi
, sup ~ SmartSym fi
, SyntacticN f fi
, sub :<: sup
)
=> sub sig -> f
sugarSym = sugarN . smartSym
sugarSymTyped
:: ( Signature sig
, fi ~ SmartFun (Typed sup) sig
, sig ~ SmartSig fi
, Typed sup ~ SmartSym fi
, SyntacticN f fi
, sub :<: sup
, Typeable (DenResult sig)
)
=> sub sig -> f
sugarSymTyped = sugarN . smartSymTyped