In Haskell, si dice che qualsiasi ADT può essere espresso come somma di prodotti. Sto cercando di trovare un tipo piatto isomorfo a Tree
, su Data.Tree
.Come scrivere un tipo che è isomorfo su Tree senza liste annidate?
Tree a = Node a [Tree a] -- has a nested type (List!)
Voglio scrivere una definizione funzionalmente identico per albero senza tipi nidificati:
Tree = ??? -- no nested types allowed
Per questo, ho provato a scrivere la relazione ricorsiva per il tipo algebre:
L a = 1 + a * L a
T a = a * L (T a)
inlining L, ho avuto:
T a = a * (1 + T a * L (T a))
T a = a * (1 * T a * (1 + T a * L (T a)))
T a = a * (1 + T a * (1 + T a * (1 + T a * L (T a))))
.210
Che non stava andando da nessuna parte, così mi sono fermato e ha fatto le moltiplicazioni, lasciandomi con:
T a = a + a * T a + a * T a * T a ...
Quale è la stessa:
T a = a * (T a)^0 + a * (T a)^1 + a * (T a)^2 ...
Quella è una somma di prodotti, ma è infinito. Non posso scriverlo in Haskell. Abusando l'algebra:
(T a) - (T a)^2 = a * T a
- (T a)^2 - a * T a + (T a) = 0
Risolvendo per T a
, ho scoperto che:
T a = 1 - a
che ovviamente non ha alcun senso. Quindi, tornando alla domanda iniziale: come appiattisco Tree
da Data.Tree
così posso scrivere un tipo che è isomorfo senza tipi annidati?
Questa domanda non è una replica di my previous question. L'ultimo riguarda la rappresentazione di tipi annidati con la codifica di Scott, per la quale la risposta corretta è "ignorare il nidificazione". Questo procede chiedendo comunque come appiattire un tipo annidato (poiché è necessario per un uso particolare di Scott Encoding, ma non obbligatorio in generale).
anche se penso che io so ciò che si vuole (e probabilmente Reid già * risolto * esso) puoi per favore aggiungi ciò che hai capito in una struttura dati * piatta *? (Perché non ti sembra la mente * ricorsione * che trovo sorprendente) – Carsten
In particolare, voglio che sia espressivo come una somma di prodotti con, sì, possibilmente, ricorsione sulla variabile legata. Es: 'data Rec a = A a (Rec a) | B a a a a | C a (Rec a) a | D a', è perfettamente valido. Ma la ricorsione su un'altra procedura ricorsiva (come il '[Tree a]' qui) non è OK. Lo voglio in particolare perché sto codificando i tipi di dati Haskell sul Lambda Calculus usando Scott Encoding, che non tiene conto dei tipi annidati, quindi devo farlo in qualche modo senza nidificare. – MaiaVictor
@Viclib 'Tree' non mi sembra problematico, per la codifica di Scott. Non dovrebbe [questo] (http://lpaste.net/134093) funzionare? –