Reputation: 113
I came across a situation recently where I needed to create a function to call a parameterless constructor. The following code demonstrates
class NoNumber() {}
val create : Unit => NoNumber = Unit => new NoNumber()
val nn = create()
This code compiles and creates a new instance of NoNumber and assigns it to nn as expected. However, there are a couple of things I wasn't expecting.
my first attempt (which doesn't compile), was as follows
val create : Unit => NoNumber = () => new NoNumber()
Why is it that Unit works and () does not work in the above example? I was under the impression that () was the one and only instance of Unit and as such the () seems to make the most sense.
Secondly I see the following warning when compiling the code
Warning:(3, 22) Adaptation of argument list by inserting () has been deprecated: this is unlikely to be what you want. signature: Function1.apply(v1: T1): R given arguments: after adaptation: Function1((): Unit) lazy val nn = create()
What does this mean and how should the code be changed to remove the warning?
Thanks
Upvotes: 1
Views: 236
Reputation: 55569
Unit => A
and () => A
are not the same thing.
Unit => A
is syntactic sugar for Function1[Unit, A]
, a function with a single argument of Unit
that returns A
. You're confusing the type Unit
with the value ()
that has type Unit
. i.e., you cannot say:
scala> val a: () = ()
<console>:1: error: '=>' expected but '=' found.
val a: () = ()
^
() => A
is syntactic sugar for Function0[A]
, a parameter-less function that returns A
. They are similar, but not quite the same.
As for the warning with this:
val create : Unit => NoNumber = Unit => new NoNumber()
If you were to have val nn = create
, then nn
would actually be a function, Unit => NoNumber
. When you have:
val nn = create()
You are actually are doing:
val nn = create.apply(())
Confusing, yes? Hence, the deprecation warning. The former is simply passing ()
to a Function1[Unit, NoNumber]
, but it looks awfully like a Function0
. What you probably want is:
val create : () => NoNumber = () => new NoNumber()
Upvotes: 7