Scala features a functional interface

I have a trait:

trait MyTrait extends (Int => MyTrait)

      

How can I constrain MyTrait

in extends like any implementations MyTrait

?

+3


source to share


2 answers


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 }
}

      

+8


source


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 }
}

      

+4


source







All Articles