Skip to content

Instantly share code, notes, and snippets.

@AndrasKovacs
Created December 1, 2018 12:19
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrasKovacs/662ca9af02f5ceda64c9314bf0f6e3f9 to your computer and use it in GitHub Desktop.
Save AndrasKovacs/662ca9af02f5ceda64c9314bf0f6e3f9 to your computer and use it in GitHub Desktop.
intrinsic deep system F syntax in Haskell
{-# language
TypeInType, GADTs, RankNTypes, TypeFamilies,
TypeOperators, TypeApplications,
UnicodeSyntax, UndecidableInstances
#-}
import Data.Kind
import Data.Proxy
data Nat = Z | S Nat
data Fin n where
FZ ∷ Fin (S n)
FS ∷ Fin n → Fin (S n)
data OPE n m where
ZZ ∷ OPE Z Z
Keep ∷ OPE n m → OPE (S n) (S m)
Drop ∷ OPE n m → OPE (S n) m
type family FinE (σ ∷ OPE n m) (x ∷ Fin m) ∷ Fin n where
FinE ZZ x = x
FinE (Drop σ) x = FS (FinE σ x)
FinE (Keep σ) FZ = FZ
FinE (Keep σ) (FS x) = FS (FinE σ x)
data Ty (n ∷ Nat) where
TyVar ∷ Fin n → Ty n
(:=>) ∷ Ty n → Ty n → Ty n
All ∷ Ty (S n) → Ty n
infixr 4 :=>
type family TyE (σ ∷ OPE n m) (a ∷ Ty m) ∷ Ty n where
TyE σ (TyVar x) = TyVar (FinE σ x)
TyE σ (a :=> b) = TyE σ a :=> TyE σ b
TyE σ (All b) = All (TyE (Keep σ) b)
type family Id n ∷ OPE n n where
Id Z = ZZ
Id (S n) = Keep (Id n)
type family WkTy (a ∷ Ty n) ∷ Ty (S n) where
WkTy (a ∷ Ty n) = TyE (Drop (Id n)) a
data Sub n m where
SNil ∷ Sub n Z
SSnoc ∷ Sub n m → Ty n → Sub n (S m)
type family CompSE (σ ∷ Sub m k)(δ ∷ OPE n m) ∷ Sub n k where
CompSE SNil δ = SNil
CompSE (SSnoc σ a) δ = SSnoc (CompSE σ δ) (TyE δ a)
type family DropS (σ ∷ Sub n m) ∷ Sub (S n) m where
DropS (σ ∷ Sub n m) = CompSE σ (Drop (Id n))
type family KeepS (σ ∷ Sub n m) ∷ Sub (S n) (S m) where
KeepS (σ ∷ Sub n m) = SSnoc (DropS σ) (TyVar FZ)
type family IdS n ∷ Sub n n where
IdS Z = SNil
IdS (S n) = KeepS (IdS n)
type family FinS (σ ∷ Sub n m)(x ∷ Fin m) ∷ Ty n where
FinS (SSnoc σ a) FZ = a
FinS (SSnoc σ a) (FS x) = FinS σ x
type family TyS (σ ∷ Sub n m)(a ∷ Ty m) ∷ Ty n where
TyS σ (TyVar x) = FinS σ x
TyS σ (a :=> b) = TyS σ a :=> TyS σ b
TyS σ (All b) = All (TyS (KeepS σ) b)
data Con n where
Nil ∷ Con Z
(:>) ∷ Con n → Ty n → Con n
SnocSt ∷ Con n → Con (S n)
infixl 4 :>
data Var ∷ ∀ n. Con n → Ty n → Type where
VZ ∷ Var (γ :> a) a
VS ∷ Var γ a → Var (γ :> b) a
VS' ∷ ∀ n (γ ∷ Con n) a. Var γ a → Var (SnocSt γ) (WkTy a)
data Tm ∷ ∀ n. Con n → Ty n → Type where
Var ∷ Var γ a → Tm γ a
Lam ∷ Tm (γ :> a) b → Tm γ (a :=> b)
App ∷ Tm γ (a :=> b) → Tm γ a → Tm γ b
Lam' ∷ Tm (SnocSt γ) b → Tm γ (All b)
-- replace Proxy with singletons if you want
App' ∷ Tm (γ ∷ Con n) (All b) → Proxy (a ∷ Ty n) → Tm γ (TyS (SSnoc (IdS n) a) b)
--------------------------------------------------------------------------------
type Ty0 = TyVar FZ
type Ty1 = TyVar (FS FZ)
type Ty2 = TyVar (FS (FS FZ))
v0 = Var VZ
v1 = Var (VS VZ)
v2 = Var (VS (VS VZ))
id' ∷ Tm Nil (All (Ty0 :=> Ty0))
id' = Lam' (Lam (Var VZ))
const' ∷ Tm Nil (All (All (Ty1 :=> Ty0 :=> Ty1)))
const' = Lam' (Lam' (Lam (Lam v1)))
apply ∷ Tm Nil (All (All ((Ty1 :=> Ty0) :=> Ty1 :=> Ty0)))
apply = Lam' (Lam' (Lam (Lam (App v1 v0))))
idApply ∷ Tm Nil (All (Ty0 :=> Ty0) :=> All (Ty0 :=> Ty0))
idApply = Lam (Lam' (Lam (App (App' (Var (VS (VS' VZ))) (Proxy @Ty0)) v0)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment