Compiler errors Ocaml错误:语法错误:';)';期待,但我找不到在哪里

Compiler errors Ocaml错误:语法错误:';)';期待,但我找不到在哪里,compiler-errors,pattern-matching,syntax-error,ocaml,Compiler Errors,Pattern Matching,Syntax Error,Ocaml,这是我的密码: 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 | [] ->

这是我的密码:

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
现在我知道我可以改进代码,并且可以在第一个匹配中包含第二个匹配,但是,我特别感兴趣的是找到错误的来源。我尝试了很多方法,但似乎没有一种方法能改变错误


因此,请随意发布改进,但我最感兴趣的是如何运行这段精确的代码,以帮助避免将来出现错误

箭头左侧的语法结构不是一个普通的表达式,而是一种模式。为了方便起见,它看起来非常像一个表达式,但其行为却非常不同。它也是纯编译时构造

例如,模式
a
,如
Lettre(uu,b,a)
中的模式将不会计算为
a
的值,或者将
a
位置的值与名为
a
的现有绑定的值相匹配。相反,它将创建一个名为
a
的新绑定,该绑定引用
a
位置的值,并对该名称以前的任何绑定进行阴影处理

因此,例如,如果您匹配的值是
Lettre('a',true,[])
a
将在箭头右侧引用值
[]
。而
b
将引用
true

除了作为将值绑定到模式中的名称的方便语法之外,不允许在模式中使用运行时值还允许编译器保证模式匹配的完备性,并在编译时对其进行优化。如果模式中允许运行时值,则必须始终提供一个通配符模式来捕获其余的可能性,因为在编译时无法知道哪些可能性在运行时匹配

我希望您现在明白为什么在模式中允许像
mot.[n]
这样的表达式,或者甚至是绑定到
mot.[n]
值的名称是没有意义的

然而,有一个独立于模式的构造,允许在模式匹配中使用运行时条件,称为“guards”或“when”子句。以您的例子:

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

这确实需要使用通配符代替
ch
来覆盖防护装置不匹配的所有情况。但是既然你已经有了,你就应该很好。

箭头左边的句法结构不是一个普通的表达式,而是一种模式。为了方便起见,它看起来非常像一个表达式,但其行为却非常不同。它也是纯编译时构造

例如,模式
a
,如
Lettre(uu,b,a)
中的模式将不会计算为
a
的值,或者将
a
位置的值与名为
a
的现有绑定的值相匹配。相反,它将创建一个名为
a
的新绑定,该绑定引用
a
位置的值,并对该名称以前的任何绑定进行阴影处理

因此,例如,如果您匹配的值是
Lettre('a',true,[])
a
将在箭头右侧引用值
[]
。而
b
将引用
true

除了作为将值绑定到模式中的名称的方便语法之外,不允许在模式中使用运行时值还允许编译器保证模式匹配的完备性,并在编译时对其进行优化。如果模式中允许运行时值,则必须始终提供一个通配符模式来捕获其余的可能性,因为在编译时无法知道哪些可能性在运行时匹配

我希望您现在明白为什么在模式中允许像
mot.[n]
这样的表达式,或者甚至是绑定到
mot.[n]
值的名称是没有意义的

然而,有一个独立于模式的构造,允许在模式匹配中使用运行时条件,称为“guards”或“when”子句。以您的例子:

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

这确实需要使用通配符代替
ch
来覆盖防护装置不匹配的所有情况。但是既然你已经有了,你就应该表现得很好。

这似乎不是一个有效的模式:
mot.[n]
。我不确定你想用它做什么,或者编译器认为它是错误的。我试图使用String.get mot s的短版本,如图所示,这当然也是无效的模式,但我想我理解你想做什么。我会在回答中解释。这似乎不是一个有效的模式:
mot.[n]
。我不确定你想用它做什么,或者编译器认为它是错误的。我试图使用String.get mot s的短版本,如图所示,这当然也是无效的模式,但我想我理解你想做什么。我会在回答中解释的。谢谢,我想我现在明白了。我本来希望mot[n]能被转换成一个字符,然后用于模式匹配,但似乎什么时候才能做到。谢谢,我想我现在明白了。我希望mot[n]能被转换成一个字符,然后用于模式匹配,但似乎什么时候才能做到这一点。