generics - Type inference and type bounds in Scala -
consider following classes:
class type { def +(other:type):type = this} class subtype extends type
now want create wrapper object takes binary function operating on type
or derived types, let's start with:
case class fct(f:(type,type) => type)
i can instantiate fct
class using _+_
apply method, cannot pass function using subtype
class, expected:
val f1 = fct(_+_) // ok val f2 = fct((x:subtype,y:type) => y) // error: found: (subtype, type) => type, required: (type, type) => type
now can define fct
using generics , type bounds accept subtypes:
case class fct[t <: type, u <: type, v <: type](f:(t,u) => v)
now f2
working expected, f1
not valid anymore, , don't understand why:
val f1 = fct(_+_) // error: missing parameter type val f2 = fct((x:subtype,y:type) => y) // ok
is there syntax accept both f1
, f2
?
edit
(reply m-z) there way around variance issues factory? like:
class fct(f:(type,type) => type) object fct { def apply(f:(type,type) => type): fct = new fct(f) def apply[t <: type, u <: type, v <: type](f:(t,u) => v): fct = new fct((x:type,y:type) => {(x,y) match { case (a:t, b:u) => f(a,b) case _ => ??? }}: type) }
the problem fct((x: subtype, y: type) => y)
not syntax, it's variance. f
in fct
has type (type, type) => type
, i.e. function2[type, type, type]
. function2
contravariant on first 2 type parameters.
this means (subtype, type) => type
is not sub-type of (type, type) => type
. therefore cannot use in place of (type, type) => type
. note fct((x: type, y: type) => y)
works fine.
with generic version of fct
, when write fct(_+_)
, there no way infer types t
, u
. best can hope in case like:
fct[subtype, type, type](_ + _)
in short, first approach work fine, function parameter types nailed down type
(or super types of that, not want). may okay though, because can still pass subtype
parameters function, cannot restrict parameters subtype
without breaking contravariance of function2
. second approach work if annotate types somewhere.
Comments
Post a Comment