co-feldspar-0.1.0.1: src/Feldspar/Sugar.hs
{-# language GADTs #-}
{-# language MultiParamTypeClasses #-}
{-# language FlexibleInstances #-}
{-# language FlexibleContexts #-}
{-# language TypeOperators #-}
{-# language TypeFamilies #-}
{-# language ScopedTypeVariables #-}
{-# language RankNTypes #-}
-- todo : is this bad? comes from how I use `sup` in the `Syntactic`
-- instance for pairs.
{-# language UndecidableInstances #-}
{-# LANGUAGE TemplateHaskell #-}
module Feldspar.Sugar where
import Feldspar.Representation
import Data.Struct
import Data.Constraint (Constraint)
import Data.Typeable (Typeable)
import Data.Proxy (Proxy(..))
import qualified Language.Haskell.TH as TH
-- syntactic.
import Language.Syntactic
import Language.Syntactic.TH
import Language.Syntactic.Syntax
import Language.Syntactic.Sugar
import Language.Syntactic.Decoration
import Language.Syntactic.Functional
import Language.Syntactic.Functional.Tuple
--------------------------------------------------------------------------------
-- ** Tuples.
--------------------------------------------------------------------------------
-- | Domains that support tuple expressions.
class Tuples dom
where
pair :: ( Type (Pred dom) a
, Type (Pred dom) b
, SyntacticN f (ASTF dom a -> ASTF dom b -> ASTF dom (a, b)))
=> f
first :: ( Type (Pred dom) a
, SyntacticN f (ASTF dom (a, b) -> ASTF dom a))
=> f
second :: ( Type (Pred dom) b
, SyntacticN f (ASTF dom (a, b) -> ASTF dom b))
=> f
instance
( Syntactic a, Type (Pred (Domain a)) (Internal a)
, Syntactic b, Type (Pred (Domain b)) (Internal b)
, Domain a ~ Domain b
, Tuples (Domain a)
)
=> Syntactic (a, b)
where
type Domain (a, b) = Domain a
type Internal (a, b) = (Internal a, Internal b)
desugar (a, b) = pair (desugar a) (desugar b)
sugar ab = (first ab, second ab)
--------------------------------------------------------------------------------
-- ** Functions.
--------------------------------------------------------------------------------
-- *** todo: replace current fix with comments once DTC bug is fixed.
instance
( Syntactic a
, Syntactic b
-- , Domain a ~ (expr :&: TypeRepF pred (RepresentationOf pred))
-- , Domain b ~ (expr :&: TypeRepF pred (RepresentationOf pred))
, (Domain a) ~ ((BindingT :+: sym) :&: TypeRepF pred (RepresentationOf pred))
, (Domain b) ~ ((BindingT :+: sym) :&: TypeRepF pred (RepresentationOf pred))
-- , BindingT :<: expr
, Type pred (Internal a)
)
=> Syntactic (a -> b)
where
type Domain (a -> b) = Domain a
type Internal (a -> b) = Internal a -> Internal b
desugar f = bepa varSym lamSym (desugar . f . sugar)
-- lamT_template varSym lamSym (desugar . f . sugar)
where
-- varSym v = inj (VarT v) :&: ValT typeRep
-- lamSym v b = Sym (inj (LamT v) :&: FunT typeRep (getDecor b)) :$ b
varSym v = InjL (VarT v) :&: ValT typeRep
lamSym v b = Sym (InjL (LamT v) :&: FunT typeRep (getDecor b)) :$ b
sugar = error "sugar not implemented for (a -> b)"
--------------------------------------------------------------------------------
apa :: (sym ~ ((BindingT :+: sym0) :&: decor)) => AST sym a -> Name
apa (Sym ((InjL (LamT n)) :&: _) :$ _) = n
apa (s :$ a) = apa s `Prelude.max` apa a
apa _ = 0
bepa :: (sym ~ ((BindingT :+: sym0) :&: decor))
=> (Name -> sym (Full a))
-> (Name -> ASTF sym b -> ASTF sym (a -> b))
-> (ASTF sym a -> ASTF sym b) -> ASTF sym (a -> b)
bepa mkVar mkLam f = mkLam v body
where
body = f $ Sym $ mkVar v
v = succ $ apa body
--------------------------------------------------------------------------------