как работает ключевое слово in в OCaml - PullRequest
0 голосов
/ 30 сентября 2018

Я знаю, как использовать ключевое слово in в OCaml.Мой вопрос в том, в каком порядке компилятор выполняет выражение.

Например, давайте возьмем следующий код:

let v = expr1 in expr2

Компилятор сначала смотрит на expr2, а затем, когда vпоявляется в expr2 заменяет v на expr1?Или сначала оценивается expr1, а затем применяется expr2?

Вы можете удивиться, почему я задаю этот странный вопрос.Это связано с тем, что я не понимаю, как работает следующий код:

let rec some_function = function 
   | [] -> () 
   | t::q when (*here put a condition*) -> some_function q
   | t::q -> (*some operations here*); some_function q
in 
let s = (*some list*)
some_function s 

Как работает этот код?Я имею в виду, когда у нас есть рекурсивный вызов some_function q, тогда программа непосредственно переходит в блок in и применяет другой рекурсивный вызов some_function s?

1 Ответ

0 голосов
/ 30 сентября 2018

Когда программа сообщает let v = expr1 in expr2, OCaml сначала оценивает expr1, а затем начинает оценку expr2 в среде, в которой v связано со значением, полученным в результате expr1.

Эта стратегия оценки, call-by-value , не единственно возможная, но это стратегия, которую использует OCaml.

Теперь давайте рассмотрим фрагмент:

let rec some_function = function ...
in
let s = (*some list*)
some_function s 

Когда программа содержит фрагмент выше, выполняются следующие шаги:

  • function ....Этот шаг короткий, потому что оценка блока function ... не означает, что код внутри ... оценивается.Вместо этого результат оценки function ... является закрытием (забывая об оптимизациях, которые применяются в вашем примере, но не в целом).
  • код, представленный (*some list*), оценивается в среде, в которой some_function связано с замыканием, обсужденным выше.
  • выражение some_function s вычисляется в среде, где some_function связано с замыканием, а s связано с результатом оценки (*some list*).В этой среде эта оценка завершается успешно и применяется замыкание, что означает, что код, который определил some_function, теперь будет выполняться (в среде, где указан его аргумент).

Замыканиесостоит из недооцененного кода и частичной среды.Среду нужно только дополнить дополнительным связыванием для аргумента, чтобы он содержал все необходимое для оценки кода.С другой стороны, пока аргумент не был предоставлен, оценка не может начаться, потому что тело функции ссылается на аргумент.

Тот факт, что some_function является рекурсивным, не меняет общую схему.Это означает только то, что при оценке тела замыкания среда также содержит привязку, связывающую тот же some_function с замыканием, так что вызов some_closure внутри тела обрабатывается так же, как и внекорпус.

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