¿Cómo se hace para hacer listas doblemente enlazadas en un lenguaje funcional puro? Es decir, algo así como Haskell en el que no estás en una mónada por lo que no tienes una mutación. ¿Es posible? (La lista enlazada con Singly es obviamente bastante fácil).Lista doblemente enlazada en un lenguaje de programación puramente funcional
Respuesta
En un lenguaje funcional puro, una lista doblemente vinculada no es tan interesante. La idea de una lista doblemente vinculada es poder tomar un nodo e ir en cualquier dirección, o para poder empalmar en el medio de una lista. En un lenguaje functionaly pura que probablemente está mejor con una de estas estructuras de dos datos:
Una lista enlazada con un puntero en el centro, desde donde se puede ir por la izquierda o hacia la derecha (una variante de Huet de "Cremallera")
Un árbol de dedo, que es una estructura de datos alucinante inventada por Ralf Hinze y Ross Paterson.
Soy un gran admirador de la cremallera; es útil en muchas situaciones.
+1 para la cremallera. +1 para el árbol de dedo. Vaya, no funciona en el sistema de votación ... :) –
Definitivamente estoy de acuerdo en que esas son opciones mucho mejores. =) –
Árboles de dedos ... interesante ... :) – sholsapp
Hay una serie de enfoques.
Si no quiere mutar la lista de doble enlace una vez que la ha construido, puede 'atar el nudo' confiando en la pereza.
http://www.haskell.org/haskellwiki/Tying_the_Knot
Si desea una lista doblemente enlazada mutable que necesita para referencias falsas de alguna manera - o utilizar los reales - al estilo del truco propuesto por Oleg Kiseylov e implementado aquí:
http://hackage.haskell.org/packages/archive/liboleg/2009.9.1/doc/html/Data-FDList.html
Curiosamente, tenga en cuenta que el primero se basa fundamentalmente en la pereza para tener éxito. En última instancia, necesitas mutación o pereza para hacer el nudo.
Reitero la pregunta de musicfan: "¿para qué necesitas esto exactamente?" Como señala Norman Ramsey: si necesita un recorrido multidireccional, entonces las cremalleras son más fáciles; si necesita un empalme rápido, los árboles con los dedos funcionan bien.
Pero, sólo para ver cómo se ve ...
import Control.Arrow
import Data.List
data LNode a = LNode { here :: a, prev :: LList a, next :: LList a }
type LList a = Maybe (LNode a)
toList :: LList a -> [a]
toList = unfoldr $ fmap $ here &&& next
fromList :: [a] -> LList a
fromList l = head nodes where
nodes = scanr ((.) Just . uncurry LNode) Nothing $ zip l $ Nothing : nodes
append :: LList a -> LList a -> LList a
append = join Nothing where
join k (Just a) b = a' where
a' = Just $ a { prev = k, next = join a' (next a) b }
join k _ (Just b) = b' where
b' = Just $ b { prev = k, next = join b' Nothing (next b) }
join _ _ _ = Nothing
En OCaml, para circular simplemente lista enlazada siempre se puede hacer algo así:
type t = { a : t Lazy.t }
let cycle n =
let rec start = {a = lazy (aux n) }
and aux = function
| 0 -> start
| n -> { a = lazy (aux (n-1))}
in start
Por lista doblemente enlazada, Me imagino que es posible hacer algo similar. Pero debes confiar en la pereza y en que los registros sean estructuras amigables cuando se trata de tipear. Lista doblemente cíclica cíclica rápida y sucia:
type 'a t = { data : 'a; before : 'a t Lazy.t; after : 'a t Lazy.t }
let of_list l =
match l with [] -> assert false | hd::tl ->
let rec start = { data = hd; before = last; after = next }
and couple = lazy (aux (lazy start) hd)
and next = lazy (Lazy.force (fst (Lazy.force couple)))
and last = lazy (Lazy.force (snd (Lazy.force couple)))
and aux before = function
| [] -> (lazy start), before
| hd::tl -> let rec current = lazy { data = hd; before = before; after = after }
and couple = lazy (aux current tl)
and after = lazy (Lazy.force (fst (Lazy.force couple)))
and last = lazy (Lazy.force (snd (Lazy.force couple))) in
current, last
in start
- 1. lista funcional pura "Verdadero" doblemente enlazada y recursos compartidos de nodos
- 2. ¿Haskell es realmente un lenguaje puramente funcional considerando UnpafePerformIO?
- 3. ¿Cómo implementar una lista doblemente enlazada en PHP?
- 4. ¿XSLT es un lenguaje de programación funcional?
- 5. Hojas de cálculo que utilizan un lenguaje de programación funcional
- 6. CMS en el lenguaje de programación funcional
- 7. ¿Qué lenguaje de programación funcional debería elegir como primer lenguaje de programación funcional?
- 8. ¿Programación orientada a objetos en un contexto de programación puramente funcional?
- 9. Javascript como un lenguaje funcional
- 10. Beneficios y usos de un lenguaje de programación funcional
- 11. localmente la edición de un árbol puramente funcional
- 12. ¿Es posible un bloqueo (espera) de una lista doblemente vinculada?
- 13. ¿Hay algún lenguaje de scripting decente que use programación funcional?
- 14. estado del desarrollo web utilizando el lenguaje de programación funcional
- 15. No se puede hacer el trabajo de la Lista doblemente enlazada
- 16. ¿Tiene C# /. Net x.x una implementación de una lista doblemente enlazada (que puede repetirse al revés)?
- 17. La "programación funcional" tiene un significado claro, pero ¿el "lenguaje funcional"?
- 18. ¿Cómo se implementaría el 'Modelo' en una aplicación web Rails en un lenguaje de programación funcional?
- 19. ¿Cuál es el algoritmo puramente funcional más eficiente para generar todos los prefijos de una lista?
- 20. Python: lista por comprensión y programación funcional
- 21. lenguaje de ensamblaje funcional
- 22. ¿Qué tan difícil es cambiar del pensamiento OOP al pensamiento de programación puramente funcional en .NET?
- 23. ¿Cuál es el lenguaje de programación funcional más mínimo?
- 24. Transmisión de lista enlazada multiproceso
- 25. Además de un lenguaje declarativo, ¿SQL es un lenguaje funcional?
- 26. SÓLIDO para programación funcional
- 27. Arquitectura de programación funcional
- 28. ¿La programación funcional es un subconjunto de la programación imperativa?
- 29. Búsqueda rápida de elementos para un lenguaje funcional (Haskell)
- 30. Programación funcional aplicada
Por curiosidad, ¿para qué exactamente necesita esto? –