packages feed

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

--------------------------------------------------------------------------------