2015-11-20 3 views
4

Я пытаюсь выяснить, как использовать currying в Scala.Scala currying и тип вывода

В следующем фрагменте:

object Foo { 

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

    def main(a:Array[String]) { 

    val f = foo(1)(2) _ 
    def g : Int => Int = foo(1)(2) 
    // def h = foo(1)(2) 

    println(f(3)) 
    println(g(3)) 
    // println(h(3)) 
    } 
} 

определения для f и g работы, один для h не:

/home/vlad/Desktop/b.scala:9: error: missing arguments for method foo in object Main; 
follow this method with `_' if you want to treat it as a partially applied function 
    def h = foo(1)(2) 

Что рассуждение позади этого является незаконным? Мне кажется, что Scala должна понять, что после звонка foo(1)(2) вы останетесь с Int => Int.

+0

Я всегда думал, что компилятор недостаточно умен для этого случая, другой вариант, который работает, - это 'def h = foo (1) (2) (_)', где вы сообщаете компилятору, что третий параметр будет в конечном итоге. –

+1

@EndeNeu Многие языки позволяют это, я думаю, Haskell среди них, так что не компилятор ведет себя скучно. Это необходимо, см. Ссылку в моем ответе. – Archeg

+0

Кроме того, в Scala частичное приложение и расширение eta ('_' в конце) фактически преобразуют метод (который не может быть частично применен) к объекту функции. Некоторые конверсии являются рискованными, когда они используются неявно, поэтому они не допускаются. В Haskell нет конверсий, это всегда истинное приложение. –

ответ

9

Это предназначено. Если бы это было разрешено (на некоторых языках это действительно разрешено), это заставило бы его работать, когда вы забыли указать аргумент, а вместо ошибки компиляции вы ожидали. Это происходит так часто, что авторы scala решают компромисс здесь и запрещают это обозначение.

Мартин рассказал об этом в своей книге, см. «Почему задний символ?» http://www.artima.com/pins1ed/functions-and-closures.html#8.7

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