24031

Scala: Return type of copy method when implicit evidence parameter has a representation type

Question:

Let's say I have a class with a type parameter and a method that should return a copy of the instance only if the class is parameterized with a particular trait that has a representation type. I can get that to happen pretty easily. What I can't do is put a sensible return type that method:

case class Foo[+A](a: A) { // Compiles def gotFooBar(implicit evidence: A <:< Bar[_]) = copy(a = a.Copy()) // Does not compile def gotFooBar(implicit evidence: A <:< Bar[_]): Foo[A] = copy(a = a.Copy()) } trait Bar[+B <: Bar[B]] { def Copy(): B // Return underlying type } case class Grill() extends Bar[Grill] { def Copy() = Grill() }

What is the return type of that function, or perhaps more importantly, how would I set up the types so that that was the return type? Could someone also point out how the real return type could be a supertype of Foo[A]?

Answer1:

Well, since you only require Bar[_] you get Any as result of calling a.Copy. You need a type parameter for the gotFooBar method:

case class Foo[+A](a: A) { def gotFooBar[B <: Bar[B]](implicit evidence: A <:< B): Foo[B] = { val bar = a: B copy(a = bar.Copy()) } }

The second question is, how to enforce that Foo[B] is a supertype of Foo[A]. You just need to add A as a lower bound for B:

def gotFooBar[B >: A <: Bar[B]](implicit evidence: A <:< B): Foo[B]

Answer2:

This is a follow-up answer to the answer by @0__. The situation gets a little more complicated if A has a Manifest associated with it:

case class Foo[+A : Manifest](a: A)

The method type parameter B needs a Manifest too (even if you don't use it). The usual way of adding a Manifest (: Manifest) won't work either because that isn't allowed when the method also has implicit parameters (the implicit evidence in this case). The Manifest can be put in the implicit parameter list though, like this:

def gotFooBar[B >: A <: Bar[B]] (implicit m: Manifest[B], evidence: A <:< B): Foo[B] = copy(a = a.Copy())

Recommend

  • Bootstrap 3 Nesting Issue
  • AVAssetWriterInput does not currently support AVVideoScalingModeFit - IOS Error
  • Xcode 6 doesn´t find cocoapods libraries
  • How to return only text after a comma in a string
  • How to add a post tsc build task that copy files?
  • Neo4j Cypher WITH is required between CREATE and MATCH
  • Rotate only between landscapeLeft and landscapeRight
  • Make ASP.NET web application FIPS Compliant?
  • How do I get Unity to inject a reference to HttpSessionState to a service
  • Why doesn't JPA's FetchType.LAZY work?
  • Drag file into Access, how to check the file details?
  • Can I get entire i18n labels of specific dictionary
  • How to tell if an error captured by my global.asax was displayed on the screen of the user
  • Share objects in nodejs between different instances
  • submit a comment on Instagram posts using jQuery or pure javascript
  • How to use apoc.load.csv in conjunction with apoc.create.node
  • Get All IP and Mac Address in lan
  • locationManager avoid (null) string in a Label
  • Keep play application running after putty terminal closed
  • Http Requests not getting routed to Https NodeJs
  • Intersection of characters in two strings
  • Find string between two substrings AND between string and the end of file
  • how to change the black color to Red with opencv python
  • List using with references, changes behavior when used as a member
  • Insert statement not working using execute(array()) of PDO Extension
  • Misplaced CAGradientLayer on iPhone 6s
  • How to create mirrored image effect with CSS single element
  • How to debug iBeacons and Passbook
  • Populating a database table with returned JSON
  • Adding native code to an existing Worklight hybrid app
  • Checking for valid enum types from protobufs
  • Add checkbox dynamically using angular 2
  • Disable account chooser FirebaseUI React
  • Multiplying polynomials/simplifying like terms
  • how to run a different select statement based on condition in Hive SQL
  • Codeigniniter insert data through models and controller
  • How to use FirstOrDefault inside Include
  • PHP Permalinks.. how to change?
  • Running R's aov() mixed effects model from Python using rpy2
  • ReferenceError: TextEncoder is not defined