Определите модуль и вызовите его функцию в одном файле - PullRequest
1 голос
/ 16 января 2012

Я определил модуль в файле mod.ml следующим образом:

module Area = struct
  ...
  let test : unit =
    Print.printf "haha"
  ...
end;;

Print.printf "hehe";;

Area.test

Кажется, что без ;; после end я не могу скомпилировать код с помощью ocamlc. Но мне кажется странным иметь ;; в файле Ocaml, я должен их хранить?

После генерации mod с помощью ocamlc я запускаю mod, он печатает hahahehe. Кажется, что haha печатается по определению let test : unit ... вместо его вызова Area.test. Что я, кроме как в результате, hehehaha или hahahehehaha. Кто-нибудь может объяснить, почему это не то, что я ожидал?

Ответы [ 2 ]

4 голосов
/ 17 января 2012

Когда ocamlc загружает модуль, он оценивает все определения «верхнего уровня» в том порядке, в котором они определены.В вашем случае у вас есть три определения «верхнего уровня».

  • Первое - это значение unit (единственное значение типа unit), которое связано с именем"тестовое задание".Это значение генерируется после побочного эффекта: отображение «ха-ха» (здесь модуль Area служит пространством имен, оно не задерживает вычисления);

  • Вторым являетсятакже значение unit, но без привязки имени;Это значение также генерируется с побочным эффектом: отображение «хе-хе»;

  • Последнее - это просто значение, связанное с именем «тест», т.е.unit.Однако на этот раз побочных эффектов нет, так как значение unit, связанное с именем «test», уже сгенерировано.

Если вы хотите получить побочный эффекткаждый раз, когда вы вызываете test, вам нужно использовать функцию:

let test () =  Print.printf "haha"

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

let () = Print.printf "hehe"

Или просто:

let _ = Area.test

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

4 голосов
/ 16 января 2012

Я никогда не использую ;; в моих исходных файлах, я думаю, что это часть интерфейса верхнего уровня.Для вашего кода я, вероятно, написал бы:

module Area = struct
  let test : unit -> unit =
      fun () -> Printf.printf "haha"
end

let () =
    Printf.printf "hehe";
    Area.test ()

Для чего бы это ни стоило, Area.test, поскольку вы определили, что это не функция, это просто единичное значение с побочным эффектом во время его вычисления.В моем коде я изменил его на функцию типа unit -> unit.

...