2015-04-20 2 views
1

Я начинаю изучать немного Scala, и я в основном понимаю функции, возвращающие функции и currying , но Я видел два синтаксиса для этого, и я хотел бы лучше понять различия и, может быть, немного теории позади , что происходит.функция curriable, которая возвращает функцию в scala через '=>' и (во-вторых) через 1 список arg, за которым следует еще

В первом методе (с использованием =>) я могу выполнить эту функцию, просто указав аргумент, связанный с переменной x. Однако, когда я пытаюсь сделать это со вторым подходом, компилятор говорит мне, что мне нужно указать _ wild card для второго аргумента.

Я понимаю, что мне нужно сделать, но я не уверен, зачем мне это делать . Может кто-нибудь, пожалуйста, скажите мне, что компилятор Scala здесь?

Первый метод с использованием =>

def add(x:Int) = (y:Int) => x + (-y) 
add: (x: Int)Int => Int 

scala> def adder = add(100) // x is bound to 100 in the returned closure 
adder: Int => Int 

scala> adder(1) 
res42: Int = 99 

Второй метод с использованием одного списка ARG следует другой

scala> def add2(x:Int)(y:Int) : Int = x + y 
add2: (x: Int)(y: Int)Int 

scala> def adder2 = add2(100) 
<console>:9: error: missing arguments for method add2; 
follow this method with `_' if you want to treat it 
as a partially applied function 

     def adder2 = add2(100) 
         ^

scala> def adder2 = add2(100) _ // Okay, here is the '_' 
adder2: Int => Int 

scala> adder2(1)     // Now i can call the curried function 
res43: Int = 101 

ответ

4

То, что вы видите, это разница между типами метода и типов функций. Это тонкая и иногда путающая разница. This answer содержит довольно подробное объяснение различий между типами методов и типами функций. Вот некоторые из наиболее важных пунктов для Вашего вопроса:

Функция Тип это (примерно) типа формы (T1, ..., Tn) => U, который является обобщающим для признака FunctionN в стандартной библиотеке.

A Тип метода является нецензурным типом. Это означает, что нет значения - нет объекта, нет экземпляра - с типом метода ... Тип метода - это объявление def - все о def, за исключением его тела.

Вы не можете напрямую назначить метод сделать val:

def foo(x: Int) = x 
val myFooVal = foo //does not compile 

Процесс вспенивания эты может преобразовать способ функции, которые вы можете назначить на val:

val myFooVal = foo _ 

Here - это сообщение в блоге, в котором исследуется эта-расширение немного более подробно.

Интересное в вашем примере - это то, что вы смешиваете методы с функциями.Это совершенно нормально, но это может быть частью того, что смущает вас здесь:

def add(x:Int) = (y:Int) => x + (-y) 

Это метод , который возвращает функцию, в то время как это:

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

Является ли чистый метод, который , как и со всеми методами, может быть преобразован к типу функции с использованием ETA-расширений:

add2 _ //Int => (Int => Int) 
add2(2) _ //Int => Int 

Это может быть поучительно поиграйте в REPL, чтобы увидеть, как Scala относится к т hese по-разному:

def add(x:Int) = (y:Int) => x + (-y) 
//add: (x: Int)Int => Int 

def add2(x:Int)(y:Int) = x + y 
//add2: (x: Int)(y: Int)Int 

Обратите внимание, что здесь отличается отпечаток от REPL. В первом примере мы видим, что add - это метод, который возвращает что-то типа Int => Int, которое является функцией. Во втором примере синтаксис метода сохраняется во втором аргументе.