Почему синтаксическая ошибка в этой очень простой команде печати - PullRequest
1 голос
/ 06 мая 2019

Я пытаюсь запустить следующий очень простой код:

open Str
print (Str.first_chars "testing" 0)

Однако выдается следующая ошибка:

$ ocaml testing2.ml 
File "testing2.ml", line 2, characters 0-5:
Error: Syntax error

В сообщении об ошибке больше нет подробностей.

Та же ошибка с print_endline также;или даже если там нет команды печати.Следовательно, ошибка частично: Str.first_chars "testing" 0

Документация по вышеуказанной функции из здесь выглядит следующим образом:

val first_chars: string -> int -> string

first_chars sn возвращает первые n символов s.Это та же функция, что и Str.string_before.

Добавление ; или ;; в конце второго оператора не имеет значения.

Какой правильный синтаксис для приведенного выше кода.

Редактировать: Со следующим кодом, предложенным @EvgeniiLepikhin:

open Str
let () =
    print_endline (Str.first_chars "testing" 0)

Ошибка:

File "testing2.ml", line 1:
Error: Reference to undefined global `Str'

И с этим кодом:

open Str;;
print_endline (Str.first_chars "testing" 0)

Ошибка:

File "testing2.ml", line 1:
Error: Reference to undefined global `Str'

При использовании только команды print (вместо print_endline) в приведенном выше коде ошибка:

File "testing2.ml", line 2, characters 0-5:
Error: Unbound value print

Обратите внимание, моя версия Ocaml:

$ ocaml -version
The OCaml toplevel, version 4.02.3

Я думаю, что Str должен быть встроенным, так как opam не находит его:

$ opam install Str
[ERROR] No package named Str found.

Я также попробовал следующий код, как предложенов комментариях @glennsl:

#use "topfind"
#require "str"
print (Str.first_chars "testing" 0)

Но это также дает то же самое простое syntax error.

Ответы [ 2 ]

2 голосов
/ 06 мая 2019

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

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

Функция print_endline принимает значение типа string, выводит его на стандартный выходной канал и возвращает значение типа unit.Тип unit имеет только одно значение, называемое единицей, которое может быть построено с использованием выражения ().Например, print_endline "hello, world" является выражением, которое производит это значение.Мы не можем просто бросить выражение в файл и надеяться, что оно будет скомпилировано, так как выражение не является определением.Синтаксис определения прост:

let <pattern> = <expr>

где - либо переменная, либо конструктор данных, который будет соответствовать структуре значения, создаваемого <expr>, и, возможно, переменной связывания, которая встречается вшаблон, например, следующие определения

let x = 7 * 8
let 4 = 2 * 2 
let [x; y; z] = [1; 2; 3]
let (hello, world) = "hello", "world"
let () = print_endline "hello, world"

Вы можете заметить, что результат выражения print_endline "hello, world" не привязан ни к какой переменной, а вместо этого сопоставляется со значением unit (), который можно увидеть (и действительно выглядит) пустой кортеж.Вы также можете написать

let x = print_endline "hello, world"

или даже

let _ = print_endline "hello, world"

Но всегда лучше указывать в левой части определения то, что вы ожидаете.

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

 open Str

 let () = 
    print_endline (Str.first_chars "testing" 0)

Мы будем использовать ocamlbuild для компиляции и запуска нашей программы.Модуль str не является частью стандартной библиотеки, поэтому мы должны сообщить ocamlbuild, что мы собираемся его использовать.Нам нужно создать новую папку и поместить нашу программу в файл с именем example.ml, затем мы можем скомпилировать ее с помощью следующей команды

 ocamlbuild -pkg str example.native --

Инструмент ocamlbuild выведет из суффикса nativeкакова ваша цель (в данном случае это создание приложения с собственным кодом).-- означает запуск построенного приложения, как только оно скомпилировано.Вышеупомянутая программа ничего не печатает, конечно, вот пример программы, которая напечатает некоторое приветственное сообщение перед печатью первых нулевых символов строки testing,

open Str

let () =
  print_endline "The first 0 chars of 'testing' are:";
  print_endline (Str.first_chars "testing" 0)

и вот какэто работает

$ ocamlbuild -package str example.native --
Finished, 4 targets (4 cached) in 00:00:00.
The first 0 chars of 'testing' are:

Кроме того, вместо компиляции вашей программы и запуска полученного приложения вы можете интерпретировать файл example.ml напрямую, используя инструмент верхнего уровня ocaml, который предоставляет интерактивный переводчик.Вам все еще нужно загрузить библиотеку str на верхний уровень, так как она не является частью стандартной библиотеки, которая предварительно связана с ней, вот правильный вызов

ocaml str.cma example.ml
1 голос
/ 06 мая 2019

Вы должны добавить ;; после "открыть ул":

open Str;;
print (Str.first_chars "testing" 0)

Другой вариант - объявить блок кода:

open Str
let () =
    print (Str.first_chars "testing" 0)
...