Тип list
в стандартной библиотеке OCaml является неизменным, и вы ничего не можете с ним сделать.Помещение указателя на список в изменяемой ячейке не делает сам список изменчивым.К счастью, вы можете реализовать изменяемые списки и даже следовать представлению данных lisp, например,
type ('a,'b) cell = {mutable car : 'a; mutable cdr : 'b}
Система типов будет бороться с вами, хотя :)
Кроме того, похоже, что вы 'запутанные указатели и ссылки.В OCaml все коробочные типы (такие как списки, строки, плавающие и т. Д.) Представлены в виде указателей.Непосредственные типы, такие как int
, char
, и конструкторы данных, такие как None
, My_constructor
, представлены как целочисленные теги.(Это то же представление, которое используют все современные lisps, кстати).
Ссылка - это просто тип, определенный в стандартной библиотеке как
type 'a ref = {mutable contents : 'a}
Так что это коробочный тип, который содержит изменяемый указатель на произвольное значение.Так, например, вы можете поместить туда список {contents = [1;2]}
, и он будет содержать указатель на список неизменный .Вы можете изменить contents
, чтобы он указывал на другой список, но вы не можете изменить сам список.Опять же, они неизменны, и вы не можете превратить нечто неизменное в изменчивое.
Также обратите внимание, что OCaml будет обмениваться данными, например,
let common_tail = [3;4]
let head_one = 1 :: common_tail
let head_two = 0 :: common_tail
Они оба будут иметь один и тот же хвост, например,
List.tl head_one == List.tl head_two
Обычно это довольноневинный, так как люди не часто используют изменяемые типы данных в OCaml, но вы можете создать список ссылок, к которым они также будут предоставлены, например,
let common_tail = [ref 3; ref 4]
let head_one = ref 1 :: common_tail
let head_two = ref 0 :: common_tail
И если вы сейчас установите cadr
до 33
List.hd (List.tl head_two) := 33;;
Это повлияет на оба списка
# head_one;;
- : int ref list = [{contents = 1}; {contents = 33}; {contents = 4}]
# head_two;;
- : int ref list = [{contents = 0}; {contents = 33}; {contents = 4}]