I would like to have higher-order-function Function[K=>V, K=>V] which takes a function K=>V and returns the type of the given function. For example I would like to have the following behaviour:
class Foo[K, V]() {
def apply[K1 <: K, V1 <: V](f: K1 => V1) = f
}
// dummy class hierachy
class A
class B extends A
class C extends B
// a function f: B=>B
def f(some: B): B = some
// the desired result
val result1: B => B = new Foo[A, A]()(f)
The apply method of Foo takes a B=>B and returns a B=>B. The type-parameters K and V keep track of the “highest” type Foo can take as an argument. Now, I would like Foo to extend Function like
class Bar[K, V] extends Function[K=>V, K=>V]() {
def apply(f: K => V) = f
}
val result2: B => B = new Bar[A, A]()(f)
however this does obviously not work. Is there a way to make this work?
Thanks
Edit
class Fuzz[K, V, K1 <: K, V1 <: V] extends Function[K1=>V1, K1=>V1] {
def apply(f: K1 => V1) = f
}
val result3: B => B = new Fuzz[A, A, B, B]()(f)
Also works, however I don’t wanna carry the two additional type-parameters
This cannot and should not work, because
A => Ais not a subtype ofB => B(and not a supertype either). The reason for that is that Function1 is covariant in its argument type and contravariant in its result type. Thus forA => Ato be a subtype ofB => B,Awould have to be a subtype as well as a supertype ofB. That is only the case ifAandBare in fact the same type. See the tour of Scala for a more in depth explanation of variance.