0
votes

Only v2 compiles bellow. I'd like instead to be able to call my apply method as in the v1 example. The compiler seems to be too quick to assign Nothing to my R variable

(inferred type arguments [...A,Nothing] do not conform to method apply's type parameter bounds [T1 <: Nothing,T2 <: Nothing] val v1 = apply(3)(new A)(new B))

class C
class A extends C
class B extends C

object O {
def apply[T1 <: R, T2 <: R, R](d : Int)(succ : T1)(fail : T2): R = if (d<0) succ else fail

  val v1 = apply(3)(new A)(new B)

  val v2 = apply[A, B, C](3)(new A)(new B)
}
2
The compiler has no easy way to infer R. I'm not sure why you need any type parameters at all though, because nothing is truly constrained. R could always be Any, which doesn't do much good.Michael Zajac
Because later I can do structural recursion on R (So R is supposed to be a sum type)Cristian Martin

2 Answers

0
votes

So I think I've found a solution for my question. I figured collections do something similar when adding two of different types. So this is something that infers its result automatically :

def apply[S, R >: S](d : Int)(succ : S, fail : R): R = if ( d < 0 ) succ else fail

Oddly only works when succ & fail belong to the same parameter list. I wonder why is that

0
votes

As presented, I'd just simplify the signature to def apply[R](d: Int, succ: R, fail: R): R. It has legal type parameters iff your original signature does, but the compiler can infer the single remaining type parameter much better.