Я использую описания, как они описаны здесь , как способ кодирования формы индуктивных типов данных. Однако я застрял на том, как представлять индуктивные типы, которые:
- Взаимно индуктивные
- Имеют разные индексы
Например, предположим, что мы ' у нас есть что-то вроде этого, где мы упорядочиваем разные типы:
data Foo : Set where
N : ℕ -> Foo
P : (Foo × Foo) -> Foo
data <N : ℕ -> ℕ -> Set where
<0 : (n : ℕ) -> <N zero n
<suc : (m n : ℕ) -> <N m n -> <N (suc m) (suc n)
data <P : (Foo × Foo) -> (Foo × Foo) -> Set
data <F : Foo -> Foo -> Set
data <P where
<Pair : (x1 x2 y1 y2 : Foo) -> <F x1 y1 -> <F x2 y2 -> <P (x1 , x2) (y1 , y2)
data <F where
<FN : ∀ (a b : ℕ) -> <N a b -> <F (N a) (N b)
<FP : ∀ (p1 p2 : (Foo × Foo) ) -> <P p1 p2 -> <F (P p1) (P p2)
То есть у нас есть тип бинарных деревьев с nats на листьях. У нас есть частичный порядок между деревьями, где мы сравниваем nats обычным способом, и мы сравниваем пары узлов, сравнивая их соответствующие поддеревья.
Обратите внимание, как <F
и <P
взаимно зависят друг от друга , Конечно, мы могли бы встроить это, чтобы сделать <F
и <P
одним типом, я стараюсь избегать этого, в случаях, когда <P
более сложный.
Что Мне интересно: Можно ли выразить вышеупомянутые типы частичного порядка с помощью описаний?
Я застреваю даже при попытке описать вышеупомянутые типы как фиксированную точку индексированного функтора. Обычно у нас есть индексный тип (I : Set)
, а функтор имеет тип (X : I -> Set) -> I -> Set
. Но мы не можем иметь и «Foo», и «Foo × Foo», которые мы ценим. Есть ли какой-то трюк, который позволяет нам использовать I = Foo ⊎ (Foo × Foo)
?