OCaml разделители и области - PullRequest
0 голосов
/ 13 июня 2010

Я изучаю OCaml и, хотя у меня есть многолетний опыт работы с императивными языками программирования (C, C ++, Java), у меня возникают некоторые проблемы с разделителями между объявлениями или выражениями в синтаксисе OCaml.

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

exp1; exp2; exp3

, оно будет рассматриваться как выражениекоторый возвращает значение exp3.Исходя из этого, я мог бы использовать

let t = something in exp1; exp2; exp3

, и все должно быть в порядке, верно?

Когда я должен использовать двойную точку с запятой ;;?Что именно это означает?

Существуют ли другие разделители, которые я должен использовать, чтобы избежать синтаксических ошибок?

Я приведу вам пример:

let rec satisfy dtmc state pformula = 
  match (state, pformula) with
    (state, `Next sformula) ->
        let s = satisfy_each dtmc sformula
        and adder a state = 
            let p = 0.; 
            for i = 0 to dtmc.matrix.rows do
                    p <- p +. get dtmc.matrix i state.index
            done;
            a +. p
        in
            List.fold_left adder 0. s
      | _ -> []

Это даетмне синтаксическая ошибка на | но я не понимаю почему .. что мне не хватает?Это проблема, которая часто возникает, и мне приходится пробовать много разных решений, пока она не заработает: /

Дополнительный вопрос: вместо let объявляется, что let .. in будет определять привязку var, которая сохраняется каждый раз послеоно было определено?

В основном я спрашиваю: какие разделители я должен использовать и когда я должен их использовать.Кроме того, есть ли различия, которые я должен учитывать при использовании интерпретатора ocaml, вместо этого, что компилятор ocamlc?

Заранее спасибо!

Ответы [ 3 ]

2 голосов
/ 13 июня 2010

;; используется для завершения ввода и начала интерпретации в ocaml REPL, это не имеет особого значения при компиляции с ocamlc или ocamlopt.

Вы не можете присвоить произвольное значение с помощью *Оператор 1007 *, вы должны использовать тип ref для изменяемых переменных:

let p = ref 0. in
for i = 0 to dtmc.matrix.rows do
    p := !p +. get dtmc.matrix i state.index
done;
a +. !p
2 голосов
/ 15 июня 2010

Разделитель ;; завершает сущность верхнего уровня.На уровне ocaml (интерпретаторе) он сообщает интерпретатору, что определенная часть ввода завершена и должна быть оценена.

В программах, компилируемых с ocamlc или ocamlopt, вы нене нужно так часто, как последовательный верхний уровень let (без in), module, type, exception, и подобные операторы автоматически сигнализируют о начале новой «фразы».Если вы включите выражение верхнего уровня в модуль, который должен оцениваться только на предмет его побочных эффектов (таких как генерация некоторого вывода или регистрация модуля), вам понадобится ;; перед тем, как сказать компилятору прекратить работу.компилируем предыдущую фразу и начинаем компилировать новую вещь.В противном случае, если предыдущая вещь является let, она будет предполагать, что новое выражение является частью let.Например:

let msg = "Hello, world";; (* we need ;; here *)
print_endline msg;; (* ;; is optional here, unless we have another expression *)

Когда вам нужно и не нужно, ;; несколько тонко, поэтому я обычно завершаю все свои сущности уровня модуля, поэтому мне не нужно беспокоиться о том, когдаесть и не нужно.

; используется для разделения последовательных «операторов» в пределах одного выражения .Таким образом, foo; bar - это одно последовательное выражение, состоящее из foo и bar, тогда как foo;; bar допустимо только на верхнем уровне модуля и означает два выражения.

Вкл. let без in: эта конструкция действительна только в определении модуля, а переменные, связанные таким образом, будут связаны через конец модуля.Часто это только конец файла;однако, если у вас есть вложенные модули, область его применения может быть более ограниченной.Он не работает внутри другого выражения или определения, такого как определение функции, если только он не входит в определение локального модуля.

2 голосов
/ 13 июня 2010
let p = 0.; 

Это ошибка.; должно быть in.Вы не можете использовать let без in только для определения глобальных функций, вы не можете использовать его внутри выражения.

Дополнительный вопрос: объявление с помощью let вместо этого let .. inбудет определять привязку var, которая действует каждый раз после того, как она была определена?

Вы можете использовать только одно или другое (кроме интерактивного интерпретатора, где вам разрешено смешивать выражения и определения).При определении глобальной функции или значения вам нужно let без in.Внутри выражения вам нужно let с in.

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