2016-08-11 3 views
-1

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

val c = (x:Int)=> x + 3 

здесь это означает, что принимать один аргумент типа Int и возвращает Int.

Но я не могу понять приведенный ниже код, поскольку он принимает функции как аргумент типа Int => Int, но означает, что он принимает один аргумент и возвращает Int, но при его реализации они отправляют функцию, которая принимает два Int арг.

def calculate(f: Int => Int, a: Int, b: Int) = 
    if (b != 0) f(a, b) else throw Exception("Divide by 0") 

def divide(a: Int, b: Int) = a/b 

calculate(divide, 2, 0) // => Exception 
calculate(divide, 4, 2) // => 2 

Может кто-нибудь помочь мне в понимании этого. Я ценю, если кто-то может поделиться некоторыми ссылками кода, где я могу больше узнать о HOF.

+1

Это даже не компилируется. – pedrofurla

+0

'val c = (x: Int) => x + 3' не является функцией более высокого порядка. – pedrofurla

ответ

1
def divide(a: Int, b: Int): Int = a/b 

divide является функцией (на самом деле метод), который занимает 2 Int с и возвращает 1 Int. Это также можно написать так.

val divide = (a:Int, b:Int) => a/b 

В этом случае это действительная функция, но разница между методом и функцией не обязательно касается нас здесь.

def calculate(f: (Int, Int) => Int, a: Int, b: Int): Int = ... 

calculate принять 3 аргумента. Первая, f, является функцией, которая принимает 2 Int s и возвращает 1 Int. (Обратите внимание на правильную подпись.)

calculate(divide, 77, 7) 

Invoke calculate с divide в качестве первого аргумента. Внутри calculate код divide ссылается (переименовывается) на f и вызывается как таковой. Итак, f(a, b) действительно divide(77, 7).

+0

Thnx @jwvh для объяснения, поэтому если 'def calculate (f: Int => Int, a: Int, b: Int) =', в этом мы можем отправить любую функцию, которая принимает только одно целое число и возвращает Int, мы можем отправить функция с двумя аргументами, только если у нас есть 'def calculate (f: (Int, Int) => Int, a: Int, b: Int)'. Однако мы не можем отправить функцию с двумя аргументами в 'def calculate (f: Int => Int, a: Int, b: Int) =', поскольку она принимает только одну функцию с одним аргументом. Надеюсь, я понял это правильно. –