yoko-0.3.1.2: Examples/LambdaLift/ULC.hs
{-# LANGUAGE TypeFamilies, TemplateHaskell, TypeOperators #-}
module LambdaLift.ULC where
import Data.Yoko
import Data.Yoko.TypeBasics (encode, derive)
import LambdaLift.Common
data ULC = Lam Type ULC | Var Int
| Let [Decl] ULC
| App ULC ULC deriving Show
data Decl = Decl Type ULC deriving Show
data Lam_ = Lam_ Type ULC
data Var_ = Var_ Int
data Let_ = Let_ [Decl] ULC
data App_ = App_ ULC ULC
data Decl_ = Decl_ Type ULC
type instance Range Lam_ = ULC
type instance Range Var_ = ULC
type instance Range Let_ = ULC
type instance Range App_ = ULC
type instance Range Decl_ = Decl
type instance Tag Lam_ = $(return $ encode "Lam")
type instance Tag Var_ = $(return $ encode "Var")
type instance Tag Let_ = $(return $ encode "Let")
type instance Tag App_ = $(return $ encode "App")
type instance Tag Decl_ = $(return $ encode "Decl")
concat `fmap` mapM derive [''ULC, ''Decl, ''Lam_, ''Var_, ''Let_, ''App_, ''Decl_]
type instance Rep Lam_ = Dep Type :*: Rec ULC
instance Generic Lam_ where
rep (Lam_ ty tm) = Dep ty :*: Rec tm
obj (Dep ty :*: Rec tm) = Lam_ ty tm
type instance Rep Var_ = Dep Int
instance Generic Var_ where
rep (Var_ i) = Dep i
obj (Dep i) = Var_ i
type instance Rep Let_ = Par1 [] (Rec Decl) :*: Rec ULC
instance Generic Let_ where
rep (Let_ ds tm) = Par1 (map Rec ds) :*: Rec tm
obj (Par1 ds :*: Rec tm) = Let_ (fmap unRec ds) tm
type instance Rep App_ = Rec ULC :*: Rec ULC
instance Generic App_ where
rep (App_ tm1 tm2) = Rec tm1 :*: Rec tm2
obj (Rec tm1 :*: Rec tm2) = App_ tm1 tm2
type instance Rep Decl_ = Dep Type :*: Rec ULC
instance Generic Decl_ where
rep (Decl_ ty tm) = Dep ty :*: Rec tm
obj (Dep ty :*: Rec tm) = Decl_ ty tm
type instance DCs ULC =
(N Lam_ :+: N Var_) :+: (N Let_ :+: N App_)
instance DT ULC where
disband (Lam ty tm) = DCsOf . inject $ Lam_ ty tm
disband (Var i) = DCsOf . inject $ Var_ i
disband (Let ds tm) = DCsOf . inject $ Let_ ds tm
disband (App tm1 tm2) = DCsOf . inject $ App_ tm1 tm2
instance DC Lam_ where rejoin (Lam_ ty tm) = Lam ty tm
instance DC Var_ where rejoin (Var_ i) = Var i
instance DC Let_ where rejoin (Let_ ds tm) = Let ds tm
instance DC App_ where rejoin (App_ tm1 tm2) = App tm1 tm2
type instance DCs Decl = N Decl_
instance DT Decl where
disband (Decl ty tm) = DCsOf . N $ Decl_ ty tm
instance DC Decl_ where rejoin (Decl_ ty tm) = Decl ty tm