def foo(x: Int, f: Unit => Int) = println(f())
foo(2, { Unit => 3 + 4 })
// case 1
def loop: Int = 7
foo(2, loop) // does not compile
changing loop to
// case 2
def loop(): Int = 7
foo(2, loop) // does not compile
changing loop to
// case 3
def loop(x: Unit): Int = 7 // changing according to Don's Comments
foo(2, loop) // compiles and works fine
Shouldn’t case 1 and case 2 also work? Why are they not working?
Defining foo as
def foo(x: Int, y: () => Int)
then case 2 works but not case 1.
Arent they all supposed to work, defining the functions either way?
Also I think () => Int in foo is a bad style, y:=> Int does not work. Comments?
Scala distinguishes between the following things:
None of these are equivalent, although as a convenience Scala allows you to elide empty parameter lists. (Incidentally, two empty parameter lists are also not the same.)
So, even though
Unitis written(), this is not the same as the function argument parens()for a function or method. Instead, think of()as aTuple0.So, if you say
f: Unit => Int, what you mean is “f takes one parameter, but it’s a really boring parameter because it isUnit, which must always be the same boringTuple0value()“. What you’re writing is really short forf: (Unit) => Int.If you say
f: () => Int, then you mean that “f takes no parameters and produces anInt“.If you say
f: => Int, then you mean that “delay the execution of whatever statement produces anIntvalue until we use it in this code (and re-evaluate it each time)”. Functionally, this ends up being basically the same asf: () => Int(and internally is converted into the sameFunction0class), but it has a different usage, presumably to allow for a more compact form of closures (you always omit the=>in the calling code).