15

There are many ways functions can be defined in Scala, which leads to confusion about when exactly function parameter types are required. I usually start with the simplest possible definition and work my way down until compiler errors go away. I'd rather actually understand how this works.

For example:

_ + _

(x, y) => x + y

(x: Int, y: Int) => x + y

def sum(x: Int, y: Int) = x + y // as pointed out, this is a method,
                                // which not a function

Bonus points for a link to the documentation.

Landon Kuhn
  • 76,451
  • 45
  • 104
  • 130

2 Answers2

17

Well there are some corner cases like: a recursive method must be explicitly typed, but normally the rule of thumb is as follows: types have to come from somewhere.

Either they come from the reference part:

val function: (Int, Int) => Int = _ + _

or from the object part:

val function = (x: Int, y: Int) => x + y

does not really matter. (in Scala!)

I know you question is about functions, but here is a similar example to illustrate Scala's type inference:

// no inference
val x: HashMap[String, Int] = new HashMap[String, Int]()
val x: HashMap[String, Int] = new HashMap[String, Int]

// object inference
val x: HashMap[String, Int] = new HashMap()
val x: HashMap[String, Int] = new HashMap
val x: HashMap[String, Int] = HashMap() // factory invocation

// reference inference
val x = new HashMap[String, Int]()
val x = new HashMap[String, Int]
val x = HashMap[String, Int]() // factory invocation

// full inference
val x = HashMap("dog" -> 3)

EDIT As requested I add the higher-order function case.

def higherOrderFunction(firstClassFunction: (Int, Int) => Int) = ...

can be called like this:

higherOrderFunction(_ + _) // the type of the firstClassFunction is omitted

But, this is not a special case. The type of the reference is explicitly mentioned. The following code illustrates a similar example.

var function: (Int, Int) => Int = null
function = _ + _

This is roughly equivalent to the higher-order function case.

agilesteel
  • 16,775
  • 6
  • 44
  • 55
  • 6
    There's a missing case which is very important for this question. If a method expects a function of a certain type, then you may omit the types in the when passing a function to that method. – Daniel C. Sobral Aug 03 '11 at 22:28
5

Your fourth example is a method, not a function (see this question). You must specify the types of arguments to a methods. The return type of a method can be inferred, unless the method is recursive, in which case it must be specified explicitly.

Community
  • 1
  • 1
Ben Lings
  • 28,823
  • 13
  • 72
  • 81
  • 2
    A concise list of the practical differences between methods and functions: http://stackoverflow.com/questions/3926047/debunking-scala-myths/4812176#4812176 – Aaron Novstrup Aug 03 '11 at 20:25