一般的な質問
同じものを表す 2 つの異なる方法であるデータ型のペアがあります。1 つは String で変数名を記録し、もう 1 つは Int で変数名を記録します。現在、両方とも定義されています。ただし、ここでは最初の表現だけを説明したいと思います。2 つ目の表現は何らかの関係によって生成されます。
具体例
具体的には、最初のものは STLC ターム ユニバースのユーザー定義バージョンであり、2 つ目は同じものの de Bruijn インデックス付きバージョンです。
{-# LANGUAGE RankNTypes, GADTs, DataKinds, TypeOperators, KindSignatures, PolyKinds, TypeFamilies, UndecidableInstances, FunctionalDependencies, FlexibleInstances #-}
-- * Universe of Terms * --
data Term :: Type -> * where
Var :: Id -> Term a
Lam :: Id -> Type -> Term b -> Term (a :-> b)
App :: Term (a :-> b) -> Term a -> Term b
Let :: Id -> Term a -> Term b -> Term b
Tup :: Term a -> Term b -> Term (a :*: b)
Lft :: Term a -> Term (a :+: b)
Rgt :: Term b -> Term (a :+: b)
Tru :: Term Boolean
Fls :: Term Boolean
Uni :: Term Unit
data TermIn :: Type -> * where
VarI :: Idx -> Info -> TermIn a
LamI :: Type -> TermIn b -> Info -> TermIn (a :-> b)
AppI :: TermIn (a :-> b) -> TermIn a -> TermIn b
LetI :: TermIn a -> TermIn b -> Info -> TermIn b
TupI :: TermIn a -> TermIn b -> TermIn (a :*: b)
TruI :: TermIn Boolean
FlsI :: TermIn Boolean
UniI :: TermIn Unit
-- * Universe of Types * --
data Type
= Type :-> Type
| Type :*: Type
| Type :+: Type
| Boolean
| Unit
| Void
-- * Synonyms * --
type Id = String -- * variable name
type Idx = Int -- * de-brujin's index
data Info = Rec Id String -- * store original name and extra info
Term
とに対して定義された関係が既に存在しTermIn
ます:
class DeBruijnPair a b | a -> b, b -> a where
decode :: b -> a
encode :: a -> b
instance DeBruijnPair (Term a) (TermIn a) where
decode = undefined
encode = undefined
Term
の元の名前は に保存されているため、 とTermIn
の 1 対 1 のマッピングが存在することに注意してください。Term
TermIn
質問を言い換える
Term
これでボイラー プレートがどれだけ関与しているかがわかります。これは、私が定義する洗練された抽象化と出力型に対する関数を使用して取り除きたいと考えていますTermIn
。さらに多くのコンテキストを提供するために、さまざまなラムダ計算の定式化に対して、このような外部表現と de Bruijn 表現のペアを多数作成していますが、それらすべてに 1 対 1 の関係が成り立ちます。