[英]What do these lines mean (Scala / JavaTokenParsers)?
我试图更好地了解如何进行大量解析/解释。
我很难理解以下内容:
type L = () => Long
然后以后还有其他几行
val term = chainl1(myNum, "[*/]".r ^^ {
case "*" => (u1:L, u2:L) => () => u1() * u2()
case "/" => (u1:L, u2:L) => () => u1() / u2()
})
我只是想了解这里的底层结构。 ()
到底是什么? 这些val
语句的逻辑流程是什么?
我假设这意味着“如果我们在myNum
找到*
或/
,则根据这两种情况进行匹配,然后……我不理解的逻辑很长”
type L = () => Long
描述一个参数为零且返回类型为Long的函数。 例如
def someConstant() = 5L
这里someConstant
是L
类型。
这条线
case "*" => (u1:L, u2:L) => () => u1() * u2()
将返回类型为Function2
(arity 2)的Function0
,返回类型为Function0
(arity 0),调用该Function0
时将返回u1() * u2()
。
val f = () => (x:Int) => x
可以写成
() => ((x: Int) => x)
这里f是一个具有Arity 0的函数,当调用时返回另一个具有Arity 1的函数,该函数接受Int参数并在调用时返回它。
f()(6) == 6
是真实的陈述。
ka4ell的答案是正确的,但没有提及为什么使用() => Long
而不是仅仅使用Long
:为什么使用() => Long
或L
会延迟返回Long
的计算的执行。 我们仅在需要实际结果时执行函数,这称为延迟评估。
在您的情况下:
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
如果我们分割行case "*" => (u1:L, u2:L) => () => u1() * u2()
:
case "*" =>
表示匹配*
与下一个编写的代码
(u1:L, u2:L) => {}
是具有两个类型为L
参数的函数定义
u1
和u2
是函数,因为它们的类型是L
,并且实际上是() => Long
,这意味着该函数什么都不做并返回Long
() => u1() * u2()
是不带参数的函数,它调用u1
和u2
并将其结果相乘返回: (u1:L, u2:L) => () => u1() * u2()
是具有两个参数的函数,该函数返回不带参数的函数,该函数执行第一个函数的两个参数,将它们相乘并返回结果
因此, () =>
表示没有参数的函数。 唯一的例外是case * =>
,其中=>
不属于函数,而是匹配语句
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.