Ocaml Ошибка: синтаксическая ошибка: ')' ожидается, но я не могу найти где - PullRequest
0 голосов
/ 20 февраля 2019

Вот мой код:

type noeud = Lettre of (char * bool * arbre_lex)
and arbre_lex = noeud list

exception Deja_defini of string



let rec ajoute mot arbre n =
    if existe mot arbre then raise (Deja_defini mot) else
    match arbre with
        | [] ->
            begin
                if n+1 = String.length mot then [ Lettre( mot.[n] , true , [] ) ]
                else [ Lettre ( mot.[n] , false, ajoute mot arbre (n+1) ) ]
            end
        | head::tail ->
            begin
                match head with 
                    | Lettre (mot.[n], b, a) -> (*line 19, source of error*)
                        begin
                            if n+1 = String.length mot then [ Lettre ( mot.[n] , true , a ) ]::tail 
                            else [ Lettre ( mot.[n] , b , ajoute mot a (n+1) ) ]::tail
                        end
                    | Lettre (_, b, a) -> ajoute mot tail n
            end

При компиляции я получаю следующую ошибку:

$ocamlc -o main *.ml
File "main.ml", line 19, characters 21-22:
Error: Syntax error: ')' expected
File "main.ml", line 19, characters 17-18:
Error: This '(' might be unmatched

Теперь я знаю, что могу улучшить свой код, и я могу включить второйсовпадение с первым, однако, Мне особенно интересно найти источник ошибки .Я перепробовал много вещей, но ни одна из них, похоже, не изменила ошибку.

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

1 Ответ

0 голосов
/ 20 февраля 2019

Синтаксическая конструкция в левой части стрелки - это не обычное выражение, а шаблон.Для удобства оно очень похоже на выражение, но ведет себя совершенно иначе.Это также чисто конструкция времени компиляции.

Например, шаблон a, как в Lettre (_, b, a), не будет иметь значения a или совпадать со значением в позиции a против значения существующей привязки с именем a.Вместо этого он создаст новую привязку с именем a, которая ссылается на значение в позиции a, и затеняет любую предыдущую привязку этого имени.

Так что, если, например, значение соответствуетпротив Lettre ('a', true, []), a будет, справа от стрелки, указывать значение []b будет ссылаться на true.

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

Я надеюсь,Теперь вы понимаете, почему не имеет смысла разрешать выражения, такие как mot.[n] или даже имя, связанное со значением mot.[n], в шаблонах.

Однако существует конструкция, отдельная отшаблон, который позволяет использовать условия выполнения при сопоставлении с шаблоном, которые называются «охранниками» или «когда».Используя ваш пример:

match head with 
    | Lettre (ch, b, a) when ch = mot.[n] -> ...

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

...