Override Generic Functions in Scala With "method xxx overrides nothing" Error - scala

I am learning Scala language features. I declare a class with a type parameter.
class Pair[+T](val first: T, val second: T){
// T is a covariant type. So an invariance R is introduced.
def replaceFirst[R >: T](newFirst: R) = {
new Pair(newFirst, second)
}
override def toString = "(" + first + ", " + second + ")"
}
Class Pair has a generic function replaceFirst. I declare a new class NastyDoublePair which extends Pair[Double]. And I'd like to override the generic function replaceFirst. Here is the compile error code:
class NastyDoublePair(first: Double, second: Double) extends Pair[Double](first, second){
override def replaceFirst(newFirst: Double): Pair[Double] = {
new Pair[Double](newFirst, second)
}
}
The compile error is below
Ch17.scala:143: error: method replaceFirst overrides nothing.
Note: the super classes of class NastyDoublePair contain the following, non final members named replaceFirst:
def replaceFirst[R >: Double](newFirst: R): ch17.p9.Pair[R]
override def replaceFirst(newFirst: Double): Pair[Double] = {
^
However, if I change the function replaceFirst to
def replaceFirst(newFirst: T) = {
new Pair(newFirst, second)
}
besides, change the Pair[+T] to Pair[T]. Everything goes well.
How can I fix the compile error, even if I'd like to set type parameter T to a covariant type. Otherwise, there is no solution to my case. I must use an invariant type parameter, not Pair[+T] but Pair[T]
Thanks for sharing your idea. Best wishes.

This happens because the type parameters change in NastyDoublePair, you can make this compile like follows:
class NastyDoublePair(first: Double, second: Double) extends Pair[Double](first, second){
override def replaceFirst[R >: Double](newFirst: R) = {
new Pair(newFirst, second)
}
}

Related

Scala: retrieve type parameter from generic collection (ClassTag?)

I am defining an abstract class taking a type parameter, along with several concrete classes which set this type.
abstract class GenericFoo[T: ClassTag] {
def defaultValue: T
def useTheValue(v: T): T
}
object DoubleFoo extends GenericFoo[Double] {
def defaultValue = 42.0
def useTheValue(v: Double) = v * 2
}
object IntFoo extends GenericFoo[Int] {
def defaultValue = 1337
def useTheValue(v: Int) = v + 64
}
But when storing my Foos in a mixed collection, it seems that my type parameter T always ends up being inferred up to Any.
val fooCollection:List[GenericFoo[_]] = List(DoubleFoo, IntFoo)
for {
foo <- fooCollection
defaultValue = foo.defaultValue
result = foo.useTheValue(defaultValue)
// Error: `defaultValue` has type `Any`, cannot call `useTheValue`
} yield result
Based on several answers to similar questions, I thought using type parameter wildcard (GenericFoo[_]), and maybe ClassTag would help keep type information, but I couldn't get this example to work as I wanted.
In the snippet above, I would want foo.defaultValue to be recognized as having the correct type (T) to be applicable in foo.useTheValue(). Have I missed something?
Edit: #gzm0 was prompt to suggest that I use abstract type members. My original use-case was a little more involved, as I am also defining an abstract type for a companion object. My actual code does something similar to:
trait GenericCompanion[T] {
// Some "static" members
def defaultValue: T
def useTheValue(v: T): T
}
abstract class GenericFoo[T] {
def getCompanion: GenericCompanion[T]
// Because of this operation, it's important that we have the same type `T`
def useCompanion: T = getCompanion.useTheValue(theActualValue)
val theActualValue: T
}
object ConcreteCompanion[Double] extends GenericCompanion[Double] {
// ...
}
object ConcreteFoo[Double] extends GenericFoo[Double] {
def getCompanion = ConcreteCompanion
}
Each concrete implementation of GenericFoo[T] also comes with a CompanionFoo[T]. Concrete sub-classes of GenericFoo are supposed to instantiated, while CompanionFoo[T] objects are here to hold "static" properties and operations. In this context, it is very important that the type parameter in GenericFoo is the same as the type parameter in GenericCompanion.
(I hope this is clear enough, sorry if my example is convoluted!)
This is a vanilla example for abstract type members. Try this:
abstract class GenericFoo {
type V
def defaultValue: V
def useTheValue(v: V): V
}
object DoubleFoo extends GenericFoo {
type V = Double
def defaultValue = 42.0
def useTheValue(v: Double) = v * 2
}
object IntFoo extends GenericFoo {
type V = Int
def defaultValue = 1337
def useTheValue(v: Int) = v + 64
}
val fooCollection:List[GenericFoo] = List(DoubleFoo, IntFoo)
Rest of the code remains unchanged.
If you use an abstract type member (rather than a type parameter), Scala will take track of the concrete types it knows for a given value.
From your example explained:
val foo: GenericCollection = ???
val defaultValue = foo.defaultValue
// defaultValue: foo.V
foo.useTheValue(defaultValue)
// foo.useTheValue: (foo.V): foo.V
Although the compiler does not know what true type foo.V is, it can nevertheless figure out that the type signatures match and that using calling useTheValue with defaultValue is OK.
As far as I can tell, this would also be a perfectly OK reasoning with type parameters, Scala just does not do it.
UPDATE
You can still do this, even with the more involved example:
trait GenericCompanion {
type T
// Some "static" members
def defaultValue: T
def useTheValue(v: T): T
}
abstract class GenericFoo { self =>
type T
def getCompanion: GenericCompanion { type T = self.T }
// Because of this operation, it's important that we have the same type `T`
def useCompanion: T = getCompanion.useTheValue(theActualValue)
val theActualValue: T
}
And the concrete implementations:
object ConcreteCompanionDouble extends GenericCompanion {
type T = Double
def defaultValue: Double = ???
def useTheValue(v: Double): Double = ???
// ...
}
object ConcreteFooDouble extends GenericFoo {
type T = Double
def getCompanion = ConcreteCompanionDouble
val theActualValue: Double = ???
}

Scala Stackable Trait and Self Type Incompatible Type

I have a trait called Mutatable that spits out a modified copy of an implementing class. I also have a trait I'd like to stack on top of it called CostedMutatable that keeps track of the cost of doing so. The method applyMutation returns an Option, as later I'd like to return None in cases where a particular mutation doesn't apply.
A simple version that just works on Ints (and "mutates" them by adding in new numbers) is shown below:
trait Mutatable[M] {
def applyMutation(mut : M) : Option[this.type]
}
trait CostedMutatable[M] extends Mutatable[M]{
var cost : Int = _
def getCostFor(mut : M): Int
abstract override def applyMutation(mut : M) : Option[this.type] = {
cost += getCostFor(mut)
applyMutation(mut)
}
}
object Example extends App {
case class Mutation(x: Int)
class Test(s: Int) extends Mutatable[Mutation] {
val start = s
override def applyMutation(mut: Mutation): Option[Test]
= Some(new Test(s+mut.x))
}
class CostTest(s: Int) extends Test(s) with CostedMutatable[Mutation] {
override def getCostFor(mut: Mutation): Int = 2
}
val testCost = new CostTest(5).cost
}
The problem is, this won't compile. I get the following error on compilation:
Error:(23, 18) overriding method applyMutation in trait Mutatable of type (mut: Example.Mutation)Option[Test.this.type];
method applyMutation has incompatible type
override def applyMutation(mut: Mutation): Option[Test] = Some(new Test(s+mut.x))
^
Aside from the compiler error, one other question comes to mind: am I even approaching this the right way? Should I be using F-bounded types instead? (I'll need each new implementing class to return a new copy of the concrete implementing class from applyMutation.)
Thanks in advance.
this.type is a type the only instances of which are this and Nothing. When a method returns this.type, the only allowed return value is this. In class Test applyMutation doesn't return this, but rather a completely new Test, which isn't an instance of this.type. This is why the code does not type-check.
I think what you are really trying to do is declare that applyMutation returns a value of the same class as this. Doing this does indeed require F-Bounded polymorphism. Here is a rewritten version of your code:
trait CostedMutatable[+A <: CostedMutatable[A, M], M] extends Mutatable[A, M] {
var cost : Int = _
def getCostFor(mut : M): Int
abstract override def applyMutation(mut: M): Option[A] = {
cost += getCostFor(mut)
super.applyMutation(mut)
}
}
object Example extends App {
case class Mutation(x: Int)
class Test(s: Int) extends Mutatable[Test, Mutation] {
val start = s
override def applyMutation(mut: Mutation): Option[Test]
= Some(new Test(s+mut.x))
}
class CostTest(s: Int) extends Test(s) with CostedMutatable[CostTest, Mutation] {
override def getCostFor(mut: Mutation): Int = 2
}
val testCost = new CostTest(5).cost
}

Limitations of implicit resolution or type inference

I'm trying to understand why implicit resolution (or perhaps type inference) fails for the following Scala code. In this code, compilation fails on the second to last line, but succeeds on a modified version of the line where types are explicitly provided.
object O {
trait Wrapper[-A, +B] {
def func: A => B
}
object Identity
implicit class Identity2Wrapper[A](self: Identity.type) extends Wrapper[A, A] {
override def func: A => A = identity
}
// Compilation fails on the next line with error:
// found String("hello")
// required: A
Identity.func("hello")
// This line compiles.
implicitly[Identity.type => Wrapper[String, String]].apply(Identity).func("hello")
}
Travis Brown seems to be right, this is an occurence of the following: https://issues.scala-lang.org/browse/SI-6472
As a proof, I could make it compile using the work around given by Travis himself here: https://issues.scala-lang.org/browse/SI-6776
object O {
trait Wrapper[-A, +B] {
val funcFunc: A => B
def func( arg: A ): B = funcFunc( arg )
}
private class Private
trait BaseWrappable {
// Dummy method (cannot ever be called, just a work around to help the compiler)
def func( a: Private ) = ???
}
object Identity extends BaseWrappable
implicit class Identity2Wrapper[A](self: Identity.type) extends Wrapper[A, A] {
val funcFunc: A => A = identity
}
Identity.func("hello")
}
The code you have written is the same as:
class Identity2Wrapper[A](self: Identity.type) extends Wrapper[A, A] {
override def func: A => A = identity
}
implicit def identityToIdentityWrapper[A](self: Identity.type) = new Identity2Wrapper[A](self)
Note that the type parameter A is unbound until the the result from the call to func is used. The Scala compiler is not smart enough to look that far ahead and determine the type of A. Also, you cannot create a value of type [A] A => A in Scala. I'm actually surprised that the compiler doesn't infer A to be of type Nothing like it does when you call identityToIdentityWrapper explicitly.

Using type parameter in anonymous class in Scala

I'm trying to declare attribute of parametrized type inside anonymous class. This works in Java, in Scala (2.9) however I get compile error:
Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
This is the code:
object DemoFail extends App {
def it[T <: AnyRef](x: T) = new Iterator[T] {
var i = x // here is the error
def next = i
def hasNext = true
}
for (i ← it(int2Integer(4))) println(i)
}
I can get it to work by "erasing" types manually:
object DemoOK extends App {
def it[T <: AnyRef](x: T) = new Iterator[T] {
var i: AnyRef = x
def next = i.asInstanceOf[T]
def hasNext = true
}
for (i ← it(int2Integer(4))) println(i)
}
So the question is: why can't the compiler do it for me ?
By adding a public variable to your iterator, you create a structural type that is a subtype of Iterator. It'll work if you change i to a private variable.
I am, unfortunately, not sure why this doesn't work. But here is an alternate workaround that avoids casts:
def it[T <: AnyRef](x: T) = {
class Forever extends Iterator[T] {
var i = x
def next = i
def hasNext = true
}
new Forever
}
A quick fix would be to avoid the structural return type:
object DemoFail extends App {
// The same with an explicit (non structural) return type
// vvvvvvvvvvvvv
def it[T <: AnyRef](x: T): Iterator[T] =
new Iterator[T] {
var i = x // no more error
def next = i
def hasNext = true
}
for (i ← it(int2Integer(4))) println(i)
}
Indeed, method it on object DemoFail does not have an explicit return type. Hence this return type is inferred by the compiler.
Here, as you are overriding existing members and adding a new one to Iterator[T], the inferred return type of the method it is a structural type of the form Iterator[T] with Object {def next: T; var i : T; def hasNext: Boolean} (as an IDE like IntelliJ can suggest).
Thus you are defining a method whose return type is a structural type that uses an abstract type of this same method. This is what bothers scalac (structural type with same method's abstract type).

scala: override implicit parameter to constructor

I have a class that takes an implicit parameter which is used by functions called inside class methods. I want to be able to either override that implicit parameter, or alternatively, have the implicit argument be copied from its source. As an example:
def someMethod()(implicit p: List[Int]) {
// uses p
}
class A()(implicit x: List[Int]) {
implicit val other = List(3) // doesn't compile
def go() { // don't want to put implicit inside here since subclasses that override go() have to duplicate that
someMethod()
}
}
The behavior I want is that someMethod() gets an implicit parameter that is some changed version of x, which was the class's implicit parameter. I want to be able to either mutate x without changing it for whatever passed it into A's constructor, or otherwise override it to a new value of my choosing. Both approaches don't seem to work. That is, it doesn't copy the list in the former case, and the compiler finds an ambiguous implicit value for the latter case. Is there a way to do this?
I realize that I can redefine the implicit value within go(), but this is not a good choice in my case because this class is subclassed numerous times, and I'd like to handle this implicit change in the base class only. So it doesn't necessarily need to go in the constructor, but it must be in a method other than go().
Introduce another wrapper type, simply to disambiguate:
// badly named, choose something domain-specific
case class ListHolder(theList: List[Int])
def someMethod()(implicit holder: ListHolder) {
val xs = holder.theList
// uses xs ...
}
class A()(implicit xs: List[Int]) {
implicit val other = ListHolder(42 :: xs) // compiles
def go() {
// xs is never considered for the implicit param to someMethod()
// because it's now the wrong type
}
}
This also makes the code more self-documenting, as it becomes blindingly obvious that the two implicits are not one and the same.
If you want to have zillions of implicits floating around that don't collide with each other, you can create a wrapper class that you can tag with marker traits for implicit usage. There are a variety of syntaxes you could use; here's one example:
object Example {
class Implication[A,B](val value: A) {
def apply[C](c: C) = new Implication[C,B](c)
}
object Implication {
def mark[B] = new Implication[Unit,B](())
implicit def implication_to_value[A,B](i: Implication[A,B]) = i.value
}
trait One {}
trait Two {}
implicit val x = Implication.mark[One]("Hello")
implicit val y = Implication.mark[Two]("Hi")
def testOne(implicit s: Implication[String,One]) = println(s: String)
def testTwo(implicit s: Implication[String,Two]) = println(s: String)
def testThree(s: String) = println("String is " + s)
def main(args: Array[String]) {
testOne
testTwo
testThree(x)
testThree(y)
}
}
Which works as you would hope:
scala> Example.main(Array())
Hello
Hi
String is Hello
String is Hi
Since you have to use a wrapper object, it's not super-efficient, but it can be very effective. (Or very confusing, given how much happens implicitly.)
This modification compiles. I changed x into a var:
class A()(implicit var x: List[Int]) {
def someMethod()(implicit p: List[Int]) {
// uses p
}
x = List(3)
def go() { // don't want to put implicit inside here since subclasses that override go() have to duplicate that
someMethod()
}
}