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
537 views
in Technique[技术] by (71.8m points)

scala - How do I create an explicit companion object for a case class which behaves identically to the replaced compiler provided implicit companion object?

I have a case class defined as such:

case class StreetSecondary(designator: String, value: Option[String])

I then define an explicit companion object:

object StreetSecondary {
  //empty for now
}

The act of defining the explicit companion object StreetSecondary causes the compiler produced "implicit companion object" to be lost; i.e. replaced with no ability to access the compiler produced version. For example, the tupled method is available on case class StreetSecondary via this implicit companion object. However, once I define the explicit companion object, the tupled method is "lost".

So, what do I need to define/add/change to the above StreetSecondary explicit companion object to regain all the functionality lost with the replacement of the compiler provided implicit companion object? And I want more than just the tupled method restored. I want all functionality (for example, including extractor/unapply) restored.

Thank you for any direction/guidance you can offer.


UPDATE 1

I have done enough searching to discover several things:

A) The explicit companion object must be defined BEFORE its case class (at least that is the case in the Eclipse Scala-IDE WorkSheet, and the code doesn't work in the IntelliJ IDE's WorkSheet regardless of which comes first).

B) There is a technical trick to force tupled to work (thank you drstevens): (StreetSecondary.apply _).tupled While that solves the specific tupled method problem, it still doesn't accurately or completely describe what the scala compiler is providing in the implicit companion object.

C) Finally, the explicit companion object can be defined to extend a function which matches the signature of the parameters of the primary constructor and returns an instance of the case class. It looks like this:

object StreetSecondary extends ((String, Option[String]) => StreetSecondary) {
  //empty for now
}

Again, I am still not confident accurately or completely describes what the scala compiler is providing in the implicit companion object.

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

When defining an explicit companion object for a case class (as of Scala 2.11), to fully replace the compiler provided functionality in the lost implicit companion object, the basic template for the explicit companion object has two requirements:

Requirements:
1. Must extend a function definition which consists of a tuple (exactly matching the type and order of the case class constructor parameters) returning the type of the case class
2. Must override the toString function to provide the object class name (identical to that of the associated case class)

Here's the original example code for the "empty" explicit companion object:

object StreetSecondary {
  //empty for now
}

And here is the example code after implementing the above requirements:

object StreetSecondary extends ((String, Option[String]) => StreetSecondary) {
    //replace the toString implementation coming from the inherited class (FunctionN)
    override def toString =
      getClass.getName.split("""$""").reverse.dropWhile(x => {val char = x.take(1).head; !((char == '_') || char.isLetter)}).head
}

To meet requirement 1 above, extends ((String, Option[String]) => StreetSecondary) is inserted right after the object name and before the first curly brace.

To meet requirement 2 above, override def toString = getClass.getName.split("""$""").reverse.dropWhile(x => {val char = x.take(1).head; !((char == '_') || char.isLetter)}).head is inserted in the body of the object (the explicit implementation remains questionable)

Deep appreciation to @drstevens for his posting the javap output to help me gain confidence the above two steps are all that are required to restore the lost functionality.


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

...