Is it possible to specify an anonymous function's return type, in Scala?
Asked Answered
I

3

29

I know you can create an anonymous function, and have the compiler infer its return type:

val x = () => { System.currentTimeMillis }

Just for static typing's sake, is it possible to specify its return type as well? I think it would make things a lot clearer.

Inattention answered 18/1, 2010 at 19:6 Comment(0)
N
30

In my opinion if you're trying to make things more clear it is better to document the expectation on the identifier x by adding a type annotation there rather than the result of the function.

val x: () => Long = () => System.currentTimeMillis

Then the compiler will ensure that the function on the right hand side meets that expectation.

Nadabb answered 18/1, 2010 at 19:19 Comment(6)
Not sure what you mean with that the function on the left hand side meets that expectation, setting a type for the result block also ensures that the type is correct, e.g. val x = () => { System.currentTimeMillis } : String does not compile. Or do you mean something else?Castrato
Geoff's answer has the advantage that you get the full type up front. If you have a long (multi-line) function definition, it's fastest to understand what's going on if the type is at the beginning. Fabian's answer has the advantage of being less repetitive (esp. good for short (one-line) definitions, and faster to understand if you can grok the whole thing in one glance).Amiss
Oh, now I see Geoff's point, his type definition contains the input type, which here is (), and that gets checked when the function () => System.currentTimeMillis is assigned to x.Castrato
Yeah, that's it exactly. I really meant to say right hand side not left hand side.Nadabb
Which is equivalent to Function0[Long], though I usually prefer the shown notation.Doty
I'm still studying Scala, and I'm in trouble in order to understand what is going on here. Why are there 2 ()in the anonymous function definition? Or, are two anonymous functions being defined at the same time? Sorry for the necroposting.Fourdimensional
C
59
val x = () => { System.currentTimeMillis } : Long
Castrato answered 18/1, 2010 at 19:10 Comment(2)
This resolved my problem. This made a lot less verbose than using the Function# approach.Satin
seems like val x = () => Long = {blah} would be a more intuitive syntax. Thanks for the answer!Infinity
N
30

In my opinion if you're trying to make things more clear it is better to document the expectation on the identifier x by adding a type annotation there rather than the result of the function.

val x: () => Long = () => System.currentTimeMillis

Then the compiler will ensure that the function on the right hand side meets that expectation.

Nadabb answered 18/1, 2010 at 19:19 Comment(6)
Not sure what you mean with that the function on the left hand side meets that expectation, setting a type for the result block also ensures that the type is correct, e.g. val x = () => { System.currentTimeMillis } : String does not compile. Or do you mean something else?Castrato
Geoff's answer has the advantage that you get the full type up front. If you have a long (multi-line) function definition, it's fastest to understand what's going on if the type is at the beginning. Fabian's answer has the advantage of being less repetitive (esp. good for short (one-line) definitions, and faster to understand if you can grok the whole thing in one glance).Amiss
Oh, now I see Geoff's point, his type definition contains the input type, which here is (), and that gets checked when the function () => System.currentTimeMillis is assigned to x.Castrato
Yeah, that's it exactly. I really meant to say right hand side not left hand side.Nadabb
Which is equivalent to Function0[Long], though I usually prefer the shown notation.Doty
I'm still studying Scala, and I'm in trouble in order to understand what is going on here. Why are there 2 ()in the anonymous function definition? Or, are two anonymous functions being defined at the same time? Sorry for the necroposting.Fourdimensional
S
13

Fabian gave the straightforward way, but some other ways if you like micromanaging sugar include:

val x = new (() => Long) {
  def apply() = System.currentTimeMillis
}

or

val x = new Function0[Long] {
  def apply() = System.currentTimeMillis
}

or even

val x = new {
  def apply(): Long = System.currentTimeMillis
}

since in most situations it makes no difference if it descends from Function, only whether it has an apply.

Sherburne answered 19/1, 2010 at 1:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.