{-# LANGUAGE GADTs, ExistentialQuantification, KindSignatures #-}

module Interp3a where

-- No scoping errors for this interpreter
-- No typing errors 

{-
open import Data.Unit
open import Data.Product
open import Data.Nat
-}

data Var :: * -> * -> * where
  VZ   :: forall g t. Var (t , g) t
  VS   :: forall g t' t. Var g t -> Var (t , g) t 

data Exp :: * -> * -> * where 
  EVar :: forall g t. Var g t -> Exp g t
  ELit :: forall g. Int -> Exp g Int 
  ELam :: forall g a b. Exp (a, g) b -> Exp g (a -> b)
  EApp :: forall g a b. Exp g (a -> b) -> Exp g a -> Exp g b

sLookup :: forall g t. Var g t -> g -> t
sLookup VZ     (v , g) = v
sLookup (VS x) (v , g) = sLookup x g

interp :: forall g t. g -> Exp g t -> t
interp e (EVar x)     = sLookup x e
interp e (ELit i)     = i
interp e (ELam t)     = \x -> interp (x , e) t
interp e (EApp t1 t2) = (interp e t1) (interp e t2)

t0 = interp () (EApp (ELam (EVar VZ)) (ELit 2))

-- doesn't type check
-- t1 = interp () (Var (S Z))

-- doesn't type check
-- t2 = interp () (App (Lit 2) (Lit 3))


