Общий вопросКак бы вы абстрагироваться от шаблонного в этой паре «похожи фасонных» типов данных
У меня есть пару типов данных, которые являются два различных способа представления то же самое, один записывает имя переменной в String, а другой записывает имя переменной в Int. В настоящее время они оба определены. Однако я хотел бы описать только первое представление, а второе - каким-то образом.
Конкретный пример
В частности, первый из них является определенный пользователем вариант термина STLC вселенной, а второй является де Брейна индексированные версии одного и того же:
{-# 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
, существует взаимно однозначное сопоставление Term
по TermIn
и обратно.
Пересчитать Вопрос
Теперь вы можете видеть, сколько плиты котла участвуют, который я хотел бы избавиться от использования каких-то элегантные абстракций, где я определяю Term
и некоторые функции над типами выходами TermIn
. Чтобы обеспечить еще больший контекст, я создаю много пар таких внешних и де Брюйновских представлений для различных формул лямбда-исчисления, и для всех из них существует взаимно однозначное отношение.
Помните, что не всем нравятся настоящие персонажи, человек. –
@JonPurdy, что такое «настоящие персонажи»? – chibro2
@ chibro2 (я надеюсь, что он означает использование ★ вместо *.) –