我对OCaml中的关联性感到非常困惑。
我们先来看一些例子。
1. +
是联想还是对吗?
我认为它是联想的。这意味着如果我们有a + b + c + d
,那么它是((a+b)+c)+d
。
但是,如果我们做f1 1 + f2 2
怎么办?它会抛出错误吗?因为它应该是((f1 1)+f2) 2
,对吧?
2. ::
是正确的联想,但如果与,
一起使用会怎么样?
如果我们做4,3::[]
,那么我们有[4,3]
。它将创建一个元组(4,3)
,然后::
进入[]
。
那为什么4,3::5,6::[]
没有工作?
功能
假设我们有let f x y = y x 5
,所以y
是一个带两个参数的函数。
如果我们做f 1 + 2
,因为+
实际上是一个带两个参数的函数,为什么f 1 + 2
不起作用?为什么+
不成为f
的参数?
正确的联想
如何创建具有正确关联性的中缀函数?
基本上,我想我还没有理解OCaml中的整个关联/优先级事物。
我知道那里有像这样的桌子http://caml.inria.fr/pub/docs/manual-caml-light/node4.9.html。但有人可以向我解释更多吗?
运算符关联性确定在有多个具有相同优先级的运算符时如何解析表达式。例如,a + b + c
有两个具有相同优先级的运算符(+
和+
),因此关联性决定了如何解析该表达式:运算符是左关联的,因此表达式等同于(a + b) + c
。
在表达式f1 1 + f2 2
中,并置(f1 1
和f2 2
)具有比+
更高的优先级,因此表达式等同于(f1 1) + (f2 2)
。在同一优先级别上没有两个或更多运算符,因此关联性无关紧要。
你关于4,3::[]
的陈述是错误的:::
的优先级高于,
,所以它被解析为4, (3::[])
,而不是(4,3)::[]
。结果是一对,其第二个元素是列表。读取4,3::5,6::[]
的类型错误:它等同于(4, (3::5), (6::[]))
,因此编译器抱怨5
的类型为int
但是上下文(由于::
运算符)需要一个列表。
当你写f 1 + 2
时,它被解析为(f 1) + 2
。函数f
应用于整数参数;因为f
需要两个参数,结果是一个函数(等待第二个参数),但+
运算符需要一个整数,因此表达式是错误的。 +
不是f
的参数,因为+
本身不是表达式,函数的参数是表达式。
我不知道你的意思是“具有正确联想的中缀函数”。 Ocaml中运算符的关联性和优先级由运算符的第一个字符确定,如链接表中所示。
这些都是解析中的标准概念,适用于几乎所有的编程语言。我建议阅读任何有关编程语言语法或解析的章节的教科书,或者从关于associativity和precedence的维基百科文章开始。