Given this simple code snippet I am astounded to provoke a stack overflow this easy:
implicit def foobar: Unit = implicitly[Unit]
In my little more complex use case I have the following situtation:
abstract class Foo {
type Repr_Tpe
protected implicit def repr2Ordered: Repr_Tpe => Ordered[Repr_Tpe]
}
class Bar extends Foo {
type Repr_Tpe = Long
protected implicit def repr2Ordered = implicitly[Repr_Tpe => Ordered[Repr_Tpe]]
}
Defining method repr2Ordered
in class Foo
does not work because type Repr_Tpe
is abstract. So I decided to copy & paste the declaration and make a definition out of it; apparently leading to the stack overflow from above. Only by removing the modifier implicit
from the definition in class Bar
solves this problem.
Isn't there an elegant solution circumventing this pitfall?
You've defined foobar
to be the implicit value of type Unit
. Then you've defined it as the implicit value of type Unit
. Thinking of it this way:
implicit def foobar: Unit = implicitly[Unit]
// you've defined foobar as the implicit value for Unit.
// so implicitly[Unit] is the same as calling foobar
// which is the same as:
implicit def foobar: Unit = foobar
You should be no more surprised that this causes a stack overflow than you would be by this statement:
def tharSheBlows: Unit = tharSheBlows
For something with a bit more elegance, I would use a view bound to ensure that the type paramater is Ordered
instead.
scala> abstract class Foo[Repr_Tpe <% Ordered[Repr_Tpe]] {}
defined class Foo
scala> class Bar extends Foo[Long] {}
defined class Bar
scala> case class Unordered(data: String)
defined class Unordered
scala> class Bam extends Foo[Unordered] {}
<console>:10: error: No implicit view available from Unordered => Ordered[Unordered].
class Bam extends Foo[Unordered] {}
^
scala> implicit def bringOrder(u: Unordered) = new Ordered[Unordered] { def compare(that: Unordered) = u.data.compareTo(that.data) }
bringOrder: (u: Unordered)java.lang.Object with Ordered[Unordered]
scala> class Bam extends Foo[Unordered] {}
defined class Bam