Мне часто говорят, что с помощью модуля Lazy
в OCaml можно делать все, что вы можете сделать на ленивом языке, таком как Haskell. Чтобы проверить это утверждение, я пытаюсь написать функцию, которая преобразует обычный список в статический дважды связанный список в ocaml.
type 'a dlist = Dnil | Dnode of 'a dlist * 'a * 'a dlist
Учитывая этот тип, я могу вручную создать несколько статических дважды связанных списков:
let rec l1 = Dnode (Dnil,1,l2)
and l2 = Dnode (l1,2,l3)
and l3 = Dnode (l2,3,Dnil)
но я хотел бы написать функцию типа 'a list -> 'a dlist
, которая при условии, что любой список создает статический двусвязный список в OCaml. Например, для данного [1;2;3]
он должен вывести что-то эквивалентное l1
выше.
Алгоритм довольно простой для записи в Haskell:
data DList a = Dnil | Dnode (DList a) a (DList a)
toDList :: [a] -> DList a
toDList l = go Dnil l
where
go _ [] = Dnil
go h (x:xs) = let r = Dnode h x (go r xs) in r
но мне не удалось выяснить, куда поместить вызовы на Lazy
, чтобы получить это для компиляции в OCaml.