Recently, I've played with type-level programming in Scala, and found the following:
trait NextPage[Curr, Next] {
def next : Next
}
class Foo
class Bar
class X(val year : Int)
object X {
implicit def xToNextPage[Y](x : X) : NextPage[X, Y] =
if (x.year == 2010) {
new X(x.year) with NextPage[X, Bar] {
def next = new Bar
}
}
else {
new X(x.year) with NextPage[X, Foo] {
def next = new Foo
}
}
}
val x = new X(2010)
val y = x.next //BOOM!
The last line freezes the interpreter indefinitely. What is strange, that if you alter just one line of code from this:
implicit def xToNextPage[Y](x : X) : NextPage[X, Y] =
to that
implicit def xToNextPage(x : X) : NextPage[X, _] =
computation will be performed successfully (but resulting type will be lost, of course).
Do you have any idea why this is the case? I believe, that it's connected with type-inference somehow...
Well the cause is that it is in infinite recursion, thanks to implicit conversion. Remove
implicit
keyword fromxToNextPage
and it shows an error:Obviously your function declaration says that you are returning
NextPage[X, Y]
but you actually returnNextPage[X,Any]
.It goes in recursion because when marked as
implicit
because your function return type is of[X, Y]
. But because you are returning[X,Any]
, it again calls the implicit functionxToNextPage
to try converting it.Solution: Change declaration to: