Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

scala - Adaptation of argument list by inserting () has been deprecated

I'm just in the process of upgrading from Scala 2.10.x to 2.11.2 and I'm receiving the following warning with the following code:

  override def validateKey(key: String): Either[InvalidKeyError, Unit] = 
    keys.contains(key) match {
      case true => Right()
      case false => Left(InvalidKeyError(context, key))
    }

Adaptation of argument list by inserting () has been deprecated: this is unlikely to be what you want. signature: Right.apply[A, B](b: B): scala.util.Right[A,B] given arguments: after adaptation: Right((): Unit)

I am able to solve this by changing the "true" case statement to:

case true => Right(()) //() is a shortcut to a Unit instance

Is this the proper way to address this warning?

Edit: perhaps a "why we have to do this now" type answer would be appropriate, my cursory investigation seems to indicate that Scala inserting "Unit" when it thinks it needs to causes other problems

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Automatic Unit inference has been deprecated in scala 2.11, and the reason behind this is that it can lead to confusing behavior, especially for people learning the language.

Here's an example

class Foo[T](value: T)
val x = new Foo

This should not compile, right? You are calling the constructor with no arguments, where one is required. Surprisingly, until scala 2.10.4 this compiles just fine, with no errors or warnings.

And that's because the compiler inferred a Unit argument, so it actually replaced your code with

val x = new Foo[Unit](()) // Foo[Unit]

As the newly introduced warning message says, this is unlikely to be what you want.

Another famous example is this

scala> List(1,2,3).toSet()
// res1: Boolean = false

calling toSet() should be a compile-time error, since toSet does not take arguments, but the compiler desperately tries to make it compile, ultimately interpreting the code as

scala> List(1,2,3).toSet.apply(())

which means: test whether () belongs to the set. Since it's not the case, you get a false!

So, starting from scala 2.11, you have to be explicit if you want to pass () (aka Unit) as an argument. That's why you have to write:

Right(())

instead of

Right()

examples taken from Simplifying Scala — The Past, Present and Future by Simon Ochsenreither.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...