2014-09-26 3 views
1

В следующем коде:Какова цель внешних и внутренних параметров функции в Scala?

def product(f: Int => Int)(a:Int, b:Int): Int = 
    if (a > b) 1 
    else f(a) * product(f)(a + 1, b) 

Параметры, a и b передаются к внутренней функции, но вы могли бы написать точно такое же определение функции следующим образом:

def product(f: Int => Int, a:Int, b:Int): Int = 
    if (a > b) 1 
    else f(a) * product(f, a + 1, b) 

Так что цель отделить параметры? Другими словами, почему это:

(f: Int => Int)(a:Int, b:Int) 

, когда вы можете более четко написать:

(f: Int => Int, a:Int, b:Int) 
+0

На самом деле они не являются «внешними» или «внутренний», может быть произвольное количество списков параметров :) 'f (a: Int) (b: Double) (c: String) (d: Long)' является совершенно законным. –

ответ

0

Это зависит от того, есть ли неявный параметр (который не может быть хорошо перемешаны с простыми из них) .. .

def foo(i: Int)(implicit p: P): Foo 

... и как вы хотите назвать это ...

def foo1(a: Int)(b: Int => Boolean): Boolean 
foo1(9) { i => false } 

def foo2(a: Int, b: Int => Boolean): Boolean 
foo2(9, { i => false }) 
3

Другой особенностью нескольких списков параметров является частичное применение:

def sum3(a: Int)(b: Int)(c: Int): Int = a + b + c 

val g: Int => Int => Int = sum3(10) _ 
val h: Int => Int  = g(20) 
val r: Int    = h(30) // 10 + 20 + 30 = 60 

Вы можете частично применить функцию и получить другую функцию, которая эквивалентна исходной, но один из аргументов, фиксированных. _ после sum3(10) необходимо потому, что sum3 - это метод, а не функция, а _ преобразует методы в функции.

Это очень полезно при использовании функции высшего порядка:

def adder(x: Int)(y: Int) = x + y 

Seq(1, 2, 3, 4) map adder(10) // Seq(11, 12, 13, 14) 

Когда частично приложенный метод/функция используются в качестве аргумента вызова высшего порядка, _ не нужен, и синтаксиса становится очень кратким.

+0

Спасибо, если ваш 'f (10)' call above будет 'sum3 (10)'? –

+0

@jimmy_terra, да, вы правы, спасибо! –

1

Другим вариантом использования этой функции является то, что если вы хотите создать структуру управления, которая выглядит так, как будто она встроена в язык программирования Scala.

Например, я мог бы написать управляющую структуру с именем times, которые помогают мне выполнить блок кода ровно n раз по следующему определению метода:

// since block is call by name, it will not be evaluate when you call it. 
def times(n: Int)(block: => Any): Unit = { 
    for (i <- 0 until n) { 
    block // evaluate(execute) block 
    } 
} 

// Now I can use the times method like a control structure 
times(5) { 
    println("Hello World"); 
} 
+0

Мне нравится эта функция в scala. – sunrize920

Смежные вопросы