Advertisement
Guest User

dll ocaml

a guest
Apr 29th, 2020
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.30 KB | None | 0 0
  1.  
  2.  
  3. type 'a ref = Nil | Cons of 'a tail * 'a * 'a tail
  4. and 'a tail = unit -> 'a ref
  5.  
  6. type 'a element = {
  7. content : 'a;
  8. mutable next : 'a element option;
  9. mutable prev : 'a element option
  10. }
  11.  
  12. let create () = Nil
  13.  
  14. let is_empty t = !t = None
  15.  
  16. let insert_first l c =
  17. let n = {content = c; next = !l; prev = None} in
  18. let _ = match !l with
  19. | Some o -> (o.prev <- Some n)
  20. | None -> () in
  21. let _ = (l := Some n) in
  22. n
  23.  
  24. let insert_after n c =
  25. let n' = {content = c; next = n.next; prev = Some n} in
  26. let _ = match n.next with
  27. | Some o -> (o.prev <- (Some n'))
  28. | None -> () in
  29. let _ = (n.next <- (Some n')) in
  30. n'
  31.  
  32. let remove t elt =
  33. let prev, next = elt.prev, elt.next in
  34. let _ = match prev with
  35. | Some prev -> (prev.next <- next)
  36. | None -> t := next in
  37. let _ = match next with
  38. | Some next -> (next.prev <- prev)
  39. | None -> () in
  40. let _ = (elt.prev <- None) in
  41. let _ = (elt.next <- None) in
  42. () (* return void *)
  43.  
  44. let iter t f =
  45. let rec loop node =
  46. match node with
  47. | None -> ()
  48. | Some el ->
  49. let next = el.next in
  50. let _ = f el in
  51. loop (next)
  52. in
  53. loop !t
  54.  
  55. (*Helper functions*)
  56. let rec start x =
  57. begin match x with
  58. | Nil -> x
  59. | Cons(t,_,_) ->
  60. begin match t() with
  61. | Nil -> x
  62. | prev -> start prev
  63. end
  64. end
  65.  
  66. let rec create_new_rev prev xs =
  67. begin match xs with
  68. | Nil -> Nil
  69. | Cons(_,x,next) ->
  70. let next' = next () in
  71. let rec xs' =
  72. Cons((fun () -> prev), x, fun () -> create_new_rev xs' next')
  73. in xs'
  74. end
  75.  
  76. let cons x xs =
  77. begin match start xs with
  78. | Nil -> Cons((fun () -> Nil),x,(fun () -> Nil))
  79. | Cons(prev,y,next) ->
  80. (* [prev] should be thunked [Nil] *)
  81. let next' = next() in
  82. let rec new1 =
  83. Cons(prev, x, (fun () -> new2))
  84. and new2 =
  85. Cons((fun () -> new1), y, (fun () -> create_new_rev new2 next'))
  86. in new1
  87. end
  88.  
  89. let rec foldl_aux f acc xs =
  90. begin match xs with
  91. | Nil -> acc
  92. | Cons(_,x,t) -> foldl_aux f (f acc x) (t())
  93. end
  94.  
  95. let rec foldr_aux f xs acc k =
  96. begin match xs with
  97. | Nil -> k acc
  98. | Cons(_,x,t) -> foldr_aux f (t()) acc (fun z -> k (f x z))
  99. end
  100. let foldr f xs acc =
  101. foldr_aux f (start xs) acc (fun x -> x)
  102.  
  103. let foldl f acc xs =
  104. foldl_aux f acc (start xs)
  105.  
  106. let foldr f xs acc =
  107. foldr_aux f (start xs) acc (fun x -> x)
  108.  
  109.  
  110. (*create dll from list *)
  111. let dll_of_list l =
  112. let singly_linked =
  113. List.fold_left (fun acc x ->
  114. Cons((fun () -> Nil), x, (fun () -> acc))) (create ()) (List.rev l)
  115. in
  116. begin match singly_linked with
  117. | Nil -> Nil
  118. | Cons(_,x,next_thunk) ->
  119. let next = next_thunk () in
  120. let rec l' =
  121. Cons((fun () -> Nil),x,(fun () -> create_new_rev l' next))
  122. in l'
  123. end
  124.  
  125. (*Create list from dll*)
  126. let list_of_dll l =
  127. foldr (fun x acc -> x :: acc) l []
  128.  
  129. (*length of dll*)
  130. let length l =
  131. foldl (fun acc _ -> 1 + acc) 0 l
  132.  
  133. (*turn a dll like (1; 2; 3) into (1; 1; 2; 2; 3; 3)*)
  134. let duplicate l =
  135. (*copied length to avoid errors while testing*)
  136. foldl (fun acc _ -> 1 + acc) 0 l
  137.  
  138. (*inplace reversal of dll*)
  139. let reverse l =
  140. foldl (fun acc x -> cons x acc) (create ()) l
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement