I tried making a polymorphic identity function in Scala 3:
val f = [T] => (x: T) => x
I can now apply it to itself (f(f)
), but only once. f(f)(f)
gives me the following error:
exception while typing f.apply[(f : Function1)](f).apply of class class dotty.tools.dotc.ast.Trees$Select # -1
exception while typing f.apply[(f : Function1)](f).apply[(f : Function1)] of class class dotty.tools.dotc.ast.Trees$TypeApply # -1
exception while typing f.apply[(f : Function1)](f).apply[(f : Function1)](f) of class class dotty.tools.dotc.ast.Trees$Apply # -1
exception while typing println(f.apply[(f : Function1)](f).apply[(f : Function1)](f)) of class class dotty.tools.dotc.ast.Trees$Apply # -1
exception while typing {
val f: PolyFunction{apply: [T](x: T): T} =
{
final class $anon() extends Object(), PolyFunction {
def apply[T](x: T): T = x
}
new Object with PolyFunction {...}():PolyFunction{apply: [T](x: T): T}
}
println(f.apply[(f : Function1)](f).apply[(f : Function1)](f))
} of class class dotty.tools.dotc.ast.Trees$Block # -1
exception while typing @main() def main: Unit =
{
val f: PolyFunction{apply: [T](x: T): T} =
{
final class $anon() extends Object(), PolyFunction {
def apply[T](x: T): T = x
}
new Object with PolyFunction {...}():PolyFunction{apply: [T](x: T): T}
}
println(f.apply[(f : Function1)](f).apply[(f : Function1)](f))
} of class class dotty.tools.dotc.ast.Trees$DefDef # -1
exception while typing @scala.annotation.internal.SourceFile("src/main/scala/main.scala") final module
class
main$package$() extends Object() {
private def writeReplace(): AnyRef =
new scala.runtime.ModuleSerializationProxy(classOf[main$package.type])
@main() def main: Unit =
{
val f: PolyFunction{apply: [T](x: T): T} =
{
final class $anon() extends Object(), PolyFunction {
def apply[T](x: T): T = x
}
new Object with PolyFunction {...}():PolyFunction{apply: [T](x: T): T}
}
println(f.apply[(f : Function1)](f).apply[(f : Function1)](f))
}
} of class class dotty.tools.dotc.ast.Trees$TypeDef # -1
exception while typing package <empty> {
final lazy module val main$package: main$package$ = new main$package$()
@scala.annotation.internal.SourceFile("src/main/scala/main.scala") final
module
class main$package$() extends Object() {
private def writeReplace(): AnyRef =
new scala.runtime.ModuleSerializationProxy(classOf[main$package.type])
@main() def main: Unit =
{
val f: PolyFunction{apply: [T](x: T): T} =
{
final class $anon() extends Object(), PolyFunction {
def apply[T](x: T): T = x
}
new Object with PolyFunction {...}():
PolyFunction{apply: [T](x: T): T}
}
println(f.apply[(f : Function1)](f).apply[(f : Function1)](f))
}
}
@scala.annotation.internal.SourceFile("src/main/scala/main.scala") final class
main() extends Object() {
<static> def main(args: Array[String]): Unit =
try main$package.main catch
{
case error @ _:scala.util.CommandLineParser.ParseError =>
scala.util.CommandLineParser.showError(error)
}
}
} of class class dotty.tools.dotc.ast.Trees$PackageDef # -1
java.lang.AssertionError: assertion failed: <none> while compiling /tmp/scastie7318598556215452568/src/main/scala/main.scala
//Long stacktrace omitted
Obviously, the compiler isn’t supposed to crash like that, but even so, is my code valid according to the language specs?