Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

匿名函数和尾随Lambda

(Anonymous Functions and Trailing Lambdas)

Koka 还允许使用 fn 关键字的匿名函数表达式。例如,我们也可以不声明 encode-char 函数,而是将其作为函数表达式直接传递给 map 函数:

fun encode2( s : string, shift : int )
  s.map( fn(c)
    if c < 'a' || c > 'z' then return c
    val base = (c - 'a').int
    val rot  = (base + shift) % 26
    (rot.char + 'a')
  )

在上一个示例中,我们必须将最后一个右小括号放在最后一个大括号(fn关键字定义的匿名函数的函数体大括号,这里通过缩进省略了让编译器自己加)后面,这有点烦人。为了方便起见,Koka 允许匿名函数跟随函数调用——这也称为尾随 lambda。例如,下面是我们如何打印数字 1 到 10:

fun print10()
  for(1,10) fn(i)
    println(i)

脱糖为

for( 1, 10, fn(i){ println(i) } )

(事实上​​,由于我们将 i 参数直接传递给 println,我们也可以直接传递函数本身,如for(1,10,println)。)

例二、

fun printhi10()
  repeat(10)
    println("hi")

其中函数体脱糖为

repeat( 10, { println(hi) } )

进一步脱糖为

repeat( 10, fn(){ println(hi)} )

这对于 while 循环特别方便,因为这不是内置的控制流结构,而只是一个常规函数:

fun print11()
  var i := 10
  while { i >= 0 }
    println(i)
    i := i - 1

请注意 while 的第一个参数是如何用大括号而不是通常的小括号括起来的。在 Koka 中,小括号之间的表达式始终在函数调用之前求值,而大括号之间的表达式被挂起,并且可能永远不会被求值,也可能被多次求值(如我们的示例中)。