packages feed

PTQ-0.0.8: src/Context.hs

-----------------------------------------------------------------------------
-- |
-- Module      :  Context
-- Copyright   :  (c) Masahiro Sakai 2007-2009
-- License     :  BSD3-style (see LICENSE)
-- 
-- Maintainer:    masahiro.sakai@gmail.com
-- Stability   :  experimental
-- Portability :  non-portable

class Context a

data Empty
instance Context Empty

infixl 9 :*
infixl 9 :@

data (:*) c a 
instance Context c => Context (c :* a)

class Append c d e | c d -> e
instance Append c Empty c
instance Append c d e => Append c (d :* a) (e :* a)

data BVar ctx a where
    B0 :: BVar (c :* a) a
    BS :: BVar c a -> BVar (c :* b) a

data Expr c t where
    B    :: BVar c t -> Expr c t
    (:@) :: Expr c (a->b) -> Expr c a -> Expr c b
    Lam  :: Expr (c :* a) b -> Expr c (a->b)

type Name = String

{-
inst :: Expr (c :* a) b -> Expr c a -> Expr c b
inst (B v) x = case v of
               B0    -> x
               BS v  -> B v
inst (a :@ b) x = inst a x :@ inst b x
inst (Lam a) x  =
    case x of
    B B0     -> 
    B (BS v) -> 
-}

{-
f :: forall c d a. Expr c a -> (forall a. BVar c a -> Expr d a) -> Expr d a
f x g =
    case x of
    a :@ b -> f a g :@ f b g
    B x -> g x
    Lam y -> Lam (f y g')
        where g' :: forall b z. BVar (c :* z) b -> Expr (d :* z) b
              g' B0     = B B0
              g' (BS x) = let foo :: Expr d b
                              foo = g x
                              bar :: Expr (d :* z) b
                              bar = shift foo
                          in bar
-}

shift' :: forall c d e e' u t.
          (Append c d e, Append (c :* u) d e') =>
          (forall t. BVar e t -> BVar e' t) ->
          Expr e t -> Expr e' t
shift' v (a :@ b) = shift' v a :@ shift' v b
shift' v (B x)    = B (v x)
shift' v (Lam x)  = Lam (shift' v' x)
    where v' B0     = B0
          v' (BS x) = BS (v x)

shift0 :: Expr c t -> Expr (c :* u) t
shift0 (a :@ b) = shift0 a :@ shift0 b
shift0 (B x)    = B (v0 x)
shift0 (Lam x)  = Lam (shift1 x)

v0 :: BVar c t -> BVar (c :* u) t
v0 = BS

shift1 :: Expr (c :* a) t -> Expr (c :* u :* a) t
shift1 (a :@ b) = shift1 a :@ shift1 b
shift1 (B x)    = B (v1 x)
shift1 (Lam x)  = Lam (shift2 x)

v1 :: BVar (c :* a) t -> BVar (c :* u :* a) t
v1 B0     = B0
v1 (BS x) = BS (v0 x)

shift2 :: Expr (c :* a :* b) t -> Expr (c :* u :* a :* b) t
shift2 (a :@ b) = shift2 a :@ shift2 b
shift2 (B x)    = B (v2 x)
shift2 (Lam x)  = undefined

v2 :: BVar (c :* a :* b) t -> BVar (c :* u :* a :* b) t
v2 B0     = B0
v2 (BS x) = BS (v1 x)