Англоязычные ресурсы

Существуют англоязычные списки часто задаваемых вопросов и ответов на них:

Книги

Коаны

Избранное

Местное

  1. Туториал

    Getting Started

  2. В чём различие между "=" и "=="?

    "=" – структурное сравнение, "==" – физическое сравнение.

    Структурное сравнение – сравнение на равенство структуры значений. Если значение является массивом, его структура – массив определённой длины, состоящий из значений, поэтому при сравнении двух массивов на структурное равенство проверяется равенство длин массивов и структурное равенство каждого из их элементов. То есть, сравнение идёт рекурсивно по структуре значений. Поэтому оно может не завершаться в случаях циклических структур данных.

    Для изменяемых значений (массивов, ссылок, записей с изменяемыми полями) верно следующее: если изменение элемента/содержимого/поля a1 влечёт за собой изменение a2, то a1 == a2.

    Подробнее – смотрите описание модуля Pervasives про функции "=" и "==".

  3. Где точка входа в программу на окамле?

    Одной конкретной точки входа нет. Программа состоит из модулей, линкуемых в определённом порядке. В этом же порядке, для каждого модуля, входящего в программу, вычисляются значения верхнего уровня модуля в порядке их определения (сверху вниз). Несмотря на это, рекомендуем сделать функцию наподобие main, из которой уже вызывать основные функции программы, и вычислять значение этой функции в качестве последнего вычисляемого значения верхнего уровня последнего линкуемого модуля. Остальные значения верхнего уровня рекомендуем делать такими, чтобы они не вызывали сайд-эффектов. То есть, что-то наподобие:

    ocaml let func1 a = ... let func2 b = ... let main () = (func1 123; func2 234) let () = main ()

  4. В чём различие между let _ = .. и let () = ..?

    let _ = .. позволяет любое выражение справа – любое значение любого типа. let () = .. соответствует только значению () : unit. Если известно, что функция используется только для сайд-эффектов или, в общем случае, возвращает (), безопаснее будет использовать let () = func args, чтобы случайно не пропустить частичное применение наподобие

    ocaml let _ = Printf.printf "two ints are: %i and %i" 123

    В этом случае не будет выведено ничего (к _ будет привязана функция с типом int -> unit). let () = .. в этом случае сообщил бы, что тип этой функции не соответствует типу unit.

    Если же знаете, что функция возвращает значение известного типа (не unit), которое нужно игнорировать, можно улучшить ошибкозащищённость и поддерживаемость программы, указав, значение какого типа хотим игнорировать, например:

    ocaml let skip_line ch = let (_ : string) = input_line ch in ()

    Это полезно как для того, чтобы избежать случайного частичного применения как во время написания кода, так и на будущее: если в функцию будут добавлены параметры, будет то же самое частичное применение, не отлавливаемое компилятором в случае let _ = ...

  5. Как указать тип функции в реализации (.ml)?

  1. Много разных библиотек, модулей, функций, типов -- как найти

нужную мне сейчас функцию?

Штатный ocamlbrowser на вид не очень эстетичен, однако весьма
практичен, если научиться запускать его как
`ocamlfind ocamlbrowser -all` -- "запустить с полным списком
установленных пакетов", либо `ocamlfind ocamlbrowser -package pkg1,pkg2`
для списка выбранных пакетов.

Далее -- просмотр списка модулей, поиск по именам модулей и
значений, даже какой-то поиск по типам есть (но не работает
так, как велит интуиция, для запросов вида `'a -> 'b -> 'a` --
считает, что конкретные `'a` не связаны друг с другом).
  1. Почему конструкторы не являются функциями?

    Ответ Xavier Leroy

  2. Зачем нужно различие let и let rec?

    См. тред