È possibile avere una lista doppiamente collegata in Haskell e qual è la soluzione ideale per implementarle? Sto implementando un grafico delle scene in cui ogni widget ha un genitore e un figlio, ed è vantaggioso esaminare sia il grafico che il grafico.come implementare liste doppiamente collegate
risposta
Non è molto pratico avere una lista doppiamente collegata in Haskell, perché devi costruirlo tutto in una volta.
Ad esempio, immagina di avere un elenco [1, 2, 3, 4, 5]
che desideri rendere doppiamente collegato. Ora, immaginiamo come la lista è rappresentata:
data DoubleList a
= LeftEnd a (DoubleList a)
| Middle a (DoubleList a) (DoubleList a)
| RightEnd a (DoubleList a)
(io uso due costruttori diversi per le due estremità per semplicità)
Per costruire l'elenco di cui sopra, si deve costruire prima il primo elemento:
let e1 = LeftEnd 1 ...
Ma per costruire il primo elemento, è già bisogno di avere il secondo elemento:
let e1 = LeftEnd 1 e2
e2 = Middle 2 e1 ...
E per il secondo elemento, è necessario il terzo, ecc:
let e1 = LeftEnd 1 e2
e2 = Middle 2 e1 e3
e3 = Middle 3 e2 e4
e4 = Middle 4 e3 e5
e5 = RightEnd 5 e4
Questo è possibile fare in Haskell grazie alla valutazione pigra; questa strategia è chiamata "legare il nodo" (E non devi letteralmente metterlo tutto in un blocco let
, puoi dividere la costruzione in funzioni)
Ma, in altre parole, fare un doppio - elenco collegato, è necessario costruirlo tutto in una volta e, se si desidera modificare qualsiasi parte di esso, è necessario utilizzare uno Zipper o semplicemente effettuare una copia completa di esso ogni volta.
Si consiglia di utilizzare invece Data.Sequence
, che è un'implementazione di archiviazione sequenziale basata su albero dito ottimizzata. Supporta l'inserimento, la cancellazione e l'iterazione molto veloci pur rimanendo una struttura dati puramente funzionale.
In caso contrario, è possibile utilizzare solo le cerniere, ma utilizzarle per gli alberi anziché per gli elenchi. Ulteriori informazioni su Zippers sono disponibili su Haskell Wiki. Le cerniere si adatterebbero molto bene in questa situazione, perché offrono la funzionalità esatta che stai cercando: se visiti un albero con una chiusura lampo, ottieni l'accesso ai "genitori" della parte dell'albero che stai visitando, ma l'albero stesso non deve contenere i riferimenti genitore.
Come per la costruzione di collegamenti doppiamente lista dalla lista ('[a]'), [qui] (http://rosettacode.org/wiki/Doubly-Linked_List_%28traversal%29#Haskell) 'snippet di codice; è la funzione 'create'. – Vitus
bello per Data.Sequence! Ora c'è un tipo interessante! Anche un rapido accesso ad entrambe le estremità della lista che era esattamente quello che stavo cercando –
Dato che in Haskell non si hanno (di solito) oggetti in stile OO, è strano pensare che i dati siano auto-consapevoli. È importante notare che di solito non si fa uso dell'aggregazione nei tipi di dati Haskell, preferendo invece la composizione.
Si potrebbe voler esaminare XMonad per vedere se il loro design corrisponde alle proprie esigenze (il codice è sorprendentemente leggibile).
Si potrebbe anche voler ristrutturare il progetto in modo da non dover mai guardare in alto (ad esempio, passando "callback" per bambini).
Si potrebbe anche voler vedere se è possibile scrivere una cerniera per l'intero grafico.
- 1. differenza tra liste doppie collegate e lista doppiamente collegata
- 2. Attraversamento di liste collegate multithreading
- 3. Come implementare una lista doppiamente collegata in PHP?
- 4. Come posso creare un array di liste collegate in java?
- 5. EL variabili doppiamente annidate?
- 6. Erlang: come implementare la comprensione delle liste di Erlang?
- 7. Tabella gerarchica - come ottenere i percorsi degli elementi [liste collegate in MySQL]
- 8. Usi elenchi collegati, elenchi collegati doppiamente e così via, nella programmazione aziendale?
- 9. val pigro per implementare liste pigri a Scala
- 10. php sql che collega tra loro le chiavi primarie e straniere (liste collegate)
- 11. Implementare liste ordinabili con jQuery e Rails 3
- 12. incorpora immagini SVG collegate
- 13. Java: Applicazione di oggetti doppiamente collegati
- 14. Come decodificare un (doppiamente) 'URL-encoded' stringa in Python
- 15. Come posso creare una lista doppiamente immutabile in C#?
- 16. Come creare liste in Symfony?
- 17. Librerie predefinite collegate da gcc?
- 18. Le immagini collegate all'interno SVG
- 19. Cerca fonti collegate in Eclipse
- 20. Python - Intersezione di due liste di liste
- 21. Linq - operando su liste di liste
- 22. liste Chiesa in Haskell
- 23. Di questi 3 metodi per leggere le liste collegate dalla memoria condivisa, perché il 3 ° più veloce?
- 24. Come disegnare linee di strisce collegate in OpenGL come questa
- 25. risoluzione del riferimento di assegnazione di un OutputIterator doppiamente incrementato
- 26. Comprensione delle liste in R
- 27. Android: Verifica se le cuffie sono collegate
- 28. Parentesi collegate in Visual Studio 2008
- 29. Uso corretto librerie libdl e collegate dinamicamente
- 30. Ordine di librerie collegate in ocamlbuild
Mi spiace essere pedante, ma IMHO che chiama le liste di haskell "elenchi concatenati" o che parla di "elenchi collegati doppiamente" nel contesto di pura FP sta trascinando un sacco di bagaglio imperativo (puntatori, aggiornamenti distruttivi) nella discussione e confonde cose. – jberryman
Pertinente al tuo obiettivo se non direttamente alla tua domanda ... C'è un grafico di scena implementato nel documento "Dati enormi ma piccoli programmi" http://eprints.whiterose.ac.uk/5000/ - il codice dovrebbe sperare ancora essere pubblicamente disponibile anche se non è mai stato messo su Hackage. Purtroppo non sembra esserci molto lavoro pubblicato che copre questo dominio con la programmazione funzionale, è un peccato perché è un grande argomento. –
Piuttosto che usare una lista doppiamente collegata, in haskell è molto più semplice archiviare i dati come un albero collegato singolarmente e quindi attraversarli con una [zipper] (http://learnyouahaskell.com/zippers) – rampion