Scala Repl does not understand currying?


#1

The following code fails in REPL

def func(x: Int)(y :Int)(z : Int) : Int = x + y + z

  val a = func(1)

fails with the error

error: missing argument list for method func
       Unapplied methods are only converted to functions when a function type is expected.
       You can make this conversion explicit by writing `func _` or `func(_)(_)(_)` instead of `func`.

#2

Hi Ashwin,

this has little to do with the REPL, and fails with directly compiled code as well. Just like the error message states, a function type needs to be expected, which is not the case. You can obtain the desired behaviour in one of two ways:

  1. Explicitly give a function type to a, i.e. val a: Int => Int => Int = func(1)
  2. Suggest that a has a function type by adding an underscore, i.e. val a = func(1) _

Both options reflect that a has a function type.

Essentially, there is a difference between a properly curried function f: Int => Int => Int and a method f(x: Int)(y: Int): Int, and the conversion from the latter to the former only works, when a hint is supplied.

Best regards

Nikita


#3

I wrote a tiresome blog post about this stuff a while back, which you may or may not find helpful :wink:


#4

it now works for dotty?

Starting dotty REPL...
scala> def func(x: Int)(y :Int)(z : Int) : Int = x + y + z                                                                                                                                                                                                                                                                                                                
def func(x: Int)(y: Int)(z: Int): Int

scala> func(1)                                                                                                                                                                                                                                                                                                                                                            
val res0: Int => Int => Int = Lambda$1271/664144670@153cb763

#6

Yes , it seems to work in Dotty


#7

Not entirely surprising – Dotty tweaked the rules for eta-expansion, so that you don’t have to say myMethod _ nearly as often…