[英]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.