порядок объявления в привязках let, Haskell против OCaml - PullRequest
6 голосов
/ 06 декабря 2011

В Haskell порядок объявления в конструкциях let / where не имеет значения, например:

f x = let g1 x y = if x>y then show x else g2 y x
          g2 p q = g1 q p
      in ...

, где g2 используется в g1 до его объявления.Но в Ocaml дело обстоит иначе:

# let a = b in
  let b = 5 in
  a;;
Warning 26: unused variable b.
Error: Unbound value b

Есть ли причина, по которой OCaml не ведет себя как Haskell?В отсутствие предварительного объявления эта функция мне кажется полезной.

Это из-за строгой оценки в OCaml, но лениво в Haskell?

Ответы [ 4 ]

18 голосов
/ 06 декабря 2011

OCaml использует «let rec», чтобы указать, когда привязка в группе может ссылаться друг на друга.Без дополнительных «rec» привязка должна быть в порядке сверху вниз.Смотрите "локальные определения" в http://caml.inria.fr/pub/docs/manual-ocaml/expr.html для подробностей.

7 голосов
/ 06 декабря 2011

Не строгость как таковая, но это симптом той же проблемы.

Ocaml не является чисто функциональным, то есть произвольные вызовы функций могут выполнять произвольный ввод-вывод. Это требует, чтобы они работали в предсказуемом порядке, что требует как строгости, так и упорядоченности, которую вы заметили.

5 голосов
/ 06 декабря 2011

В Хаскеле это не из-за ленивой оценки. Выяснить, какое имя относится к тому, что происходит во время компиляции, когда все равно ничего не выполняется (строго или лениво). Помните, что в Haskell вы пишете только математические определения, а не команды, которые должны выполняться по порядку. В каком порядке вы пишете эти определения не имеет значения. Говорите ли вы

a = expr1
b = expr2

или

b = expr2
a = expr1

это означает, что a определено как expr1, а b определено как expr2.

Я не знаю OCaml, поэтому ничего не могу сказать по этому поводу.

0 голосов
/ 06 декабря 2011

Хаскелл покончил с архаичным различием let против let rec. Приличный компилятор может очень хорошо видеть, является ли это простой let или тот, который содержит взаимно рекурсивные определения и может действовать соответственно.

(Интересно, что делает компилятор ML, если он начинается с let rec, а затем имеет только нерекурсивные определения. Конечно, эта вещь let / let rec является неприятным препятствием, когда кто-то делает рефакторинг.)

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