我正在努力更好地了解如何进行大规模解析/解释。
我很难理解这些行:
type L = () => Long
然后还有其他一些行,比如
val term = chainl1(myNum, "[*/]".r ^^ {
case "*" => (u1:L, u2:L) => () => u1() * u2()
case "/" => (u1:L, u2:L) => () => u1() / u2()
})
我只是想了解这里的基础结构。这里()
究竟是什么?这些val
语句的逻辑流程是什么?
我认为这意味着"如果我们在*
中找到/
或myNum
,则根据这两种情况匹配这两种情况,然后......长逻辑流程我不明白"
答案 0 :(得分:4)
type L = () => Long
描述了一个零参数和返回类型为Long的函数。例如
def someConstant() = 5L
此处someConstant
的类型为L
。
这一行
case "*" => (u1:L, u2:L) => () => u1() * u2()
将返回一个类型为Function2
(arity 2)的函数,返回类型为Function0
(arity 0),调用时将返回u1() * u2()
的结果。
val f = () => (x:Int) => x
可以写成
() => ((x: Int) => x)
这里f是一个带有arity 0的函数,当调用when时,返回另一个arity 1函数,该函数接受Int参数并在调用时返回它。
f()(6) == 6
是真实的陈述。
答案 1 :(得分:3)
ka4ell的答案是正确的,但没有提到为什么要使用() => Long
而不是仅使用Long
:() => Long
或L
执行计算返回Long
的延迟。我们只在我们想要实际结果的时刻执行这些功能,这称为 lazy 评估。
在你的情况下:
case "*" =>
// Return a function which takes two Ls : u1 and u2
// and which returns an L : () => u1() * u2()
(u1:L, u2:L) => () => u1() * u2()
让我们定义一个返回L
的简单函数:
// return a function which will return a Long
// this could potentially be a very expensive calculation
def giveMeAnL(n: Long) = () => {
println("giveMeAnL is called")
n
}
如果我们使用的函数类似于案例中的函数:
// analogous case "*" => ...
def multiply(u1:L, u2:L) = () => {
println("multiply is called")
u1() * u2()
}
// create two Ls
val (l1, l2) = (giveMeAnL(5L), giveMeAnL(2L))
val productL = multiply(l1, l2) // productL is of type L
值productL
现在包含L
,可以计算这两个值的乘积。此时,既不计算产品也不计算两个值。如果我们调用productL
值,则会计算这两个值,并计算这些值的乘积。
val product = productL()
// multiply is called
// giveMeAnL is called
// giveMeAnL is called
// product: Long = 10
如果在解析步骤的某个位置,您想忽略某些L
值,则永远不会计算这些L
的结果,从而提高性能。
case "multiply first with 5" =>
(u1:L, u2:L) => () => u1() * 5L // u2 is never executed
答案 2 :(得分:0)
如果我们拆分行case "*" => (u1:L, u2:L) => () => u1() * u2()
:
case "*" =>
表示将*
与下次编写的代码匹配
(u1:L, u2:L) => {}
是函数的定义,它有两个类型为L
u1
和u2
是函数,因为它们的类型是L
,它实际上是() => Long
,这意味着这是一个不带任何东西并返回{{1}的函数}}
Long
是一个没有参数的函数,调用() => u1() * u2()
和u1
并将其结果相乘
回去:
u2
是两个参数的函数,它返回一个无参数的函数,它执行第一个函数的两个参数,将它们相乘并返回结果
因此,(u1:L, u2:L) => () => u1() * u2()
表示没有参数的函数。这里唯一的例外是() =>
其中case * =>
不属于某个函数,而是匹配语句