«Истинный» чисто функциональный двусвязный список и совместное использование узлов

Недавно я познакомился с этим кодом OCaml , который в Haskell можно записать как:

data DL a = DL [a] a [a]

create [] = error "empty list"
create (x:xs) = DL [] x xs

next (DL pr x (h:tl)) = DL (x:pr) h tl
next _ = error "end of dlist"

prev (DL (p:pr) x tl) = DL pr p (x:tl)
prev _ = error "start of dlist"

, который, как мне показалось, был не правильной реализацией двусвязного списка, поскольку он создает новое хранилище при обходе. OTOH есть этот код Haskell :

data DList a = Leaf | Node { prev::(DList a), elt::a, next::(DList a) }

create = go Leaf
  where go _    []     = Leaf
        go prev (x:xs) = current
            where current = Node prev x next
                  next    = go current xs

Можно ли сказать, что только этот код истинный dl-list?

Можем ли мы положиться на этот код, чтобы ввести истинное совместное использование узлов dl-list, чтобы при обходе не создавалось новое хранилище?

Всегда ли одноименная переменная в Haskell ссылается на одно и то же , или отдельные экземпляры одноименной переменной относятся к отдельной копии одного и того же? (отредактировано в добавить акцента).

9
задан Community 23 May 2017 в 12:09
поделиться