Trying to figure out why the code compiles for nested type inference on method with arity-2 but not with currying.
object Test
{
trait Version
object VersionOne extends Version
trait Request[A <: Version]
trait RequestOne extends Request[VersionOne.type]
case class HelloWorld() extends RequestOne
def test1[A <: Version, T <: Request[A]](t : T, a : A): T = t
def test2[A <: Version, T <: Request[A]](t : T)(a : A): T = t
}
// This works
Test.test1(Test.HelloWorld(), Test.VersionOne)
// This doesn't
Test.test2(Test.HelloWorld())(Test.VersionOne)
test2 fails to compile with the following error:
Error:(22, 73) inferred type arguments [Nothing,A$A96.this.Test.HelloWorld] do not conform to method test2's type parameter bounds [A <: A$A96.this.Test.Version,T <: A$A96.this.Test.Request[A]]
def get$$instance$$res1 = /* ###worksheet### generated $$end$$ */ Test.test2(Test.HelloWorld())(Test.VersionOne)
Looking forward to some insights on the same.
@DmytroMitin already explained why it does fail.
However, you can solve the problem this way, using the Partially-Applied Type trick, together with Generalized Type Constraints.
def test2[T](t: T): Test2PartiallyApplied[T] = new Test2PartiallyApplied(t)
final class Test2PartiallyApplied[T](private val t: T) extends AnyVal {
def apply[A <: Version](a: A)(implicit ev: T <:< Request[A]): T = t
}
Which you can use like this.
Test.test2(Test.HelloWorld())(Test.VersionOne)
// res: HelloWorld = HelloWorld()
Nothing
in compile error usually means that some type parameters were not inferred.
Try to specify them explicitly
Test.test2[Test.VersionOne.type, Test.RequestOne](Test.HelloWorld())(Test.VersionOne)
Difference between test1
and test2
is not only in currying. For example, generally in test2(t: ...)(a: ...)
type of a
can depend on value of t
. So for test2
type inferrence is more complicated than for test1
.
Scala type inference and multiple arguments list
Type inference with type aliases and multiple parameter list function
Multiple parameter closure argument type not inferred
What's the difference between multiple parameters lists and multiple parameters per list in Scala?