2013-05-02 7 views
2

Не могли бы вы объяснить мне, как написать сокращенную версию функции литерала?Как вы пишете сокращенную версию функционального литерала?

Я иду через this спрей учебник, в котором следующий код

val route: Route = { ctx => ctx.complete("yeah") } 

архивируется в

val route: Route = complete("yeah") 

где complete является функцией RouteDirectives.

Я не могу воспроизвести то же самое в моем коде, который

class Test 
{ 
    def testFunc(value : Int) { 
    println(value) 
    } 
} 

type MyType = Test => Unit 
val asd : MyType = _.testFunc(10) 
asd(new Test) 

Если я пишу val asd : MyType = testFunc(10) вместо этого я (очевидно) получаю ошибку

error: type mismatch; 
found : Int(10) 
required: Int => Unit 
val asd : MyType = testFunc(10) 

Так я думал, что может быть «полным» также является объектом с методом apply. И действительно следующие работы

val route: Route = complete.apply("yeah") 

Но я не вижу объекта. В отладчике он переходит в RouteDirectives.complete, как и ожидалось.

Почему? Что мне не хватает?

ответ

4

complete возвращает функцию. Когда вы вызываете complete("yeah"), вы подаете на эту функцию параметр "yeah" (они называют это магнитом).

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

def testFunc: Int => Unit = (i: Int) => println(i) 

Собираем вместе с вызовом метода на объекте Test:

def testFunc: Int => (Test => Unit) = (i: Int) => { 
    (test: Test) => println(i) 
} 

Из-за пути => правоассоциативным и типа это можно было бы переписать:

def testFunc: Int => Test => Unit = i => test => println(i) 

Это либо очень запутанно, либо естественно (параметры точно отражают типы).

Так что, когда в учебнике говорят, что это эквивалент, авторы библиотеки подходят к некоторой длине, чтобы сделать ее похожей на «эквивалентную», возвращая функции, это не то, что встроено в синтаксис Scala.

0

Я думаю, у вас была ошибка форматирования в коде. Когда я впервые вставлял ваш код в REPL, новая строка после «теста класса» привела к тому, что следующий блок обрабатывался как совершенно отдельный блок. Вы выполнили это в REPL? Следующие работал для меня:

scala> class Test { def testFunc(i: Int) { println(i) } } 
defined class Test 

scala> type MyType = Test => Unit 
defined type alias MyType 

scala> val asd : MyType = { t => t.testFunc(10) } 
asd: Test => Unit = <function1> 

scala> val asd : MyType = { _.testFunc(10) } 
asd: Test => Unit = <function1> 

scala> val asd : MyType = _.testFunc(10) 
asd: Test => Unit = <function1> 
+0

Эй @robo. Я был озадачен тем фактом, что код Spray работает без '_.' – expert

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

  • Нет связанных вопросов^_^