Scala features a functional interface
In scala, a type Function
is covariant, as denoted by + R in the signature of Function1:
trait Function1[-T1, +R] extends AnyRef
This means that you are already right. Having MyTrait
extend (Int => MyTrait)
(same as Function1[Int, MyTrait
) means that any type that extends MyTrait will have to implement a function apply
that returns any instance MyTrait
.
The following will be legal as per your current signature MyTrait
:
class Foo extends MyTrait {
def apply(x: Int): Foo = new Foo
}
class Bar extends MyTrait {
def apply(x: Int): Foo = new Foo
}
class Baz extends MyTrait {
def apply(x: Int): MyTrait = new MyTrait { def apply(y: Int) = new Baz }
}
source to share
As Dan wrote, normal behavior is to return any instance of MyTrait.
If you want to restrict it to only returning an instance of the type of the current object, you can do this:
trait MyTrait[T <: MyTrait[T]] extends (Int => T)
and then when you implement (copy from Dan)
class Foo extends MyTrait[Foo] {
def apply(x: Int): Foo = new Foo
}
class Bar extends MyTrait[Bar] {
def apply(x: Int): Foo = new Foo //Compile error
}
class Baz extends MyTrait[Baz] {
def apply(x: Int): MyTrait = new MyTrait { def apply(y: Int) = new Baz }
}
source to share