¿Es posible tener una lista doblemente vinculada en Haskell, y cuál es la solución ideal para implementarlas? Estoy implementando un gráfico de escena donde cada widget tiene un padre y un hijo, y es beneficioso mirar hacia arriba y hacia abajo en el gráfico.cómo implementar listas doblemente vinculadas
Respuesta
No es realmente práctico tener una lista doblemente vinculada en Haskell, porque tienes que construirla de una vez.
Por ejemplo, imagina que tienes una lista [1, 2, 3, 4, 5]
que deseas vincular doblemente. Ahora, imaginemos cómo se representa la lista:
data DoubleList a
= LeftEnd a (DoubleList a)
| Middle a (DoubleList a) (DoubleList a)
| RightEnd a (DoubleList a)
(I utilizar dos constructores diferentes para los dos extremos de la simplicidad)
Para construir la lista anterior, usted tiene que construir primero el primer elemento:
let e1 = LeftEnd 1 ...
Pero para construir el primer elemento, ya que tener el segundo elemento:
let e1 = LeftEnd 1 e2
e2 = Middle 2 e1 ...
Y para el segundo elemento, es necesario el tercero, etc:
let e1 = LeftEnd 1 e2
e2 = Middle 2 e1 e3
e3 = Middle 3 e2 e4
e4 = Middle 4 e3 e5
e5 = RightEnd 5 e4
Esto es posible hacerlo en Haskell, debido a la evaluación perezosa; esta estrategia se llama "atar el nudo" (Y no tienes que ponerlo literalmente en un solo bloque let
; puedes dividir la construcción en funciones)
Pero, en otras palabras, para hacer un doble- lista enlazada, necesita construirla de una vez, y si alguna vez desea cambiar alguna parte de ella, debe usar una Zipper o simplemente hacer una copia completa de la misma cada vez.
Yo recomendaría utilizar en su lugar Data.Sequence
, que es una implementación de almacenamiento secuencial optimizada basada en árbol de huellas digitales. Admite una inserción, eliminación e iteración muy rápidas y sigue siendo una estructura de datos puramente funcional.
De lo contrario, es posible que desee utilizar Cremalleras, pero úselas para Árboles en lugar de Listas. Puede encontrar más información sobre cremalleras en el Haskell Wiki. Las cremalleras encajarían muy bien en esta situación, ya que ofrecen la funcionalidad exacta que buscas: si visitas un árbol con una cremallera, obtienes acceso a los "padres" de la parte del árbol que estás visitando, pero el árbol en sí no tiene que contener las referencias principales.
En cuanto a la construcción doblemente vinculada list from list ('[a]'), [here] (http://rosettacode.org/wiki/Doubly-Linked_List_%28traversal%29#Haskell) un fragmento de código; es la función 'create'. – Vitus
bueno para Data.Sequence! ¡Ahora hay un tipo interesante! También acceso rápido a ambos extremos de la lista, que era exactamente lo que yo buscaba –
Dado que no tiene (normalmente) objetos de estilo OO en Haskell, es extraño pensar que los datos son conscientes de sí mismos. Es importante tener en cuenta que, en general, no se utiliza la agregación en los tipos de datos Haskell, lo que favorece la composición.
Es posible que desee ver en XMonad para ver si su diseño coincide con sus necesidades (el código es sorprendentemente legible).
También es posible que desee reestructurar su diseño para que nunca tenga que mirar por encima de usted (por ejemplo, al pasar "devoluciones de llamada" a los niños).
Es posible que también desee ver si puede escribir una cremallera para todo el gráfico.
- 1. Listas vinculadas recursivas en Java
- 2. ¿Cómo desasigna Fortran las listas vinculadas?
- 3. Nodo principal en listas vinculadas
- 4. Clasificación de montón usando listas vinculadas
- 5. Implementación de la pila usando listas vinculadas
- 6. Sumar y restar Bigints usando listas vinculadas
- 7. Árboles: Listas vinculadas frente a matrices (Eficiencia)
- 8. ¿Cómo implementar una lista doblemente enlazada en PHP?
- 9. Puntero a una matriz de punteros a listas vinculadas
- 10. Listas ordenadas jQuery vinculadas y colecciones de Backbone
- 11. ¿El vector es un caso especial de listas vinculadas?
- 12. Formas de implementar tareas vinculadas a la CPU en nodejs
- 13. ¿Variables EL anidadas doblemente?
- 14. Tabla jerárquica: cómo obtener las rutas de los elementos [listas vinculadas en MySQL]
- 15. Erlang: ¿cómo implementar la comprensión de listas de Erlang?
- 16. Java: Imposición de objetos doblemente vinculados
- 17. Lista doblemente enlazada en un lenguaje de programación puramente funcional
- 18. Desreferencia-asignación a una OutputIterator doblemente incrementado
- 19. ¿Cuáles son los ejemplos del mundo real de cuándo deben usarse las listas vinculadas?
- 20. Encontrar el nodo que se cruza de dos listas vinculadas que se intersectan
- 21. ¿Cómo puedo "encadenar" tablas vinculadas en Access?
- 22. Implementar listas ordenables ajax con jQuery y Rails 3
- 23. ¿Es posible un bloqueo (espera) de una lista doblemente vinculada?
- 24. Bibliotecas predeterminadas vinculadas por gcc?
- 25. Listas de listas de listas
- 26. ¿Cuál es el objetivo de la clase SplDoublyLinkedList de PHP y, más importante aún, de las listas vinculadas en general?
- 27. ¿Cómo puedo implementar 'tee' programáticamente en C?
- 28. ¿Ejecutas tareas vinculadas a la CPU con actores de Scala?
- 29. ¿Las matrices de JavaScript en realidad están vinculadas?
- 30. Dependencias del proyecto Qmake (bibliotecas vinculadas)
Lo siento ser pedante, pero en mi humilde opinión llamar listas de Haskell "listas vinculadas" o hablar de "listas doblemente vinculadas" en el contexto de pura FP está arrastrando una gran cantidad de equipaje imperativo (punteros, actualizaciones destructivas) en la discusión y confunde cosas. – jberryman
Pertinente a su objetivo, si no es directamente a su pregunta ... Hay un gráfico de escena implementado en el documento "Datos enormes, pero pequeños programas" http://eprints.whiterose.ac.uk/5000/ - el código debería, con suerte, seguir estar a disposición del público aunque nunca haya sido colocado en Hackage. Lamentablemente, no parece haber mucho trabajo publicado que cubra este dominio con programación funcional, es una pena, ya que es un gran tema. –
En lugar de utilizar una lista doblemente vinculada, es mucho más fácil en Haskell almacenar sus datos como un árbol vinculado individualmente y luego recorrerlos con un [zipper] (http://learnyouahaskell.com/zippers) – rampion