Понимание примера обязательного списка в Ocaml - PullRequest
4 голосов
/ 22 декабря 2010

Я новичок в очамле. признателен, если кто-нибудь может помочь мне понять материал представлен на стр. 94 книги "разработка приложений с объективной камерой".

не может понять смысл следующего абзаца:

Просто оценка (itl l) была проведена до оценка (ihd l), так что на последней итерации imap список ссылается на l стал пустым списком, прежде чем мы осмотрели его голову. Пример списка отныне определенно пустой, хотя мы не получили никакого результата

Пример imap (function x ! x) возвращает

Uncaught exception: Failure("hd")

вместо

- : string ilist = {c=["one"; "two"; "three"]}

Я бы подумал, что

else icons (f (ihd l)) (imap f (itl l))`

станет icons("one") ( ( icons("two") ( ( icon("three")([]) ) ) ) и вернуть

- : string ilist = {c=["one"; "two"; "three"]}

1 Ответ

4 голосов
/ 22 декабря 2010

В примере, приведенном в книге, список реализован в императивном стиле.Функция itl изменяет список, то есть изменяет список, удаляя первый элемент.После вызова itl первый элемент практически исчезает.

Сложная часть - это порядок, в котором аргументы icons выполняются в операторе:

else icons (f (ihd l)) (imap f (itl l))

В спецификации OCaml порядок не указан.В прошлый раз, когда я проверял, компилятор INRIA сначала упорядочил последний аргумент, поэтому (imap f (itl l)) выполняется перед (f (ihd l)).Это означает, что к тому моменту, когда ihd фактически вызывается, itl вызывается достаточно раз, чтобы удалить все элементы l.

В качестве примера, давайте рассмотрим предпоследний рекурсивный вызов- l это просто ["three"].Вы думаете, что это приведет к:

icons (f "three") (imap f [])

Однако давайте посмотрим, что произойдет, если мы сначала вызовем itl:

(* l = ["three"] *)
let tail = (itl l) in (* tail = [], l = [] *)
let head = (ihd l) in (* l = [], ihd raises an exception *)
icons head (imap f tail)

В качестве примера попробуйте запустить этот код:

let f x y z = x + y + z
f (print_int 1; 1) (print_int 2; 2) (print_int 3; 3)

На моей машине (OCaml 3.12) я получаю этот вывод:

321- : int = 6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...