scala bind type parameter of trait with type parameter of function
It is difficult to explain problem using few words, so I prepared pice of code to present issue.
Let's develop container of type Container[T1,T2]
and implicits for wrapping any value in that container. If the value is type of Container[T1,T2]
wrapping should return the same type. More over wrapping method should taking parameter of type T1 (the same as in container), and resulting with container with replaced T1 value. Solution must conform generics and implicits manner.
Sounds little confusing, let's read the code :)
Container:
case class Container[T1, T2](t1: T1, t2: T2)
Trait with wrapping method:
trait ToContainer[A] {
def wrappingMethod[E](e: E): Container[E, A]
}
Object with implicits:
object ToContainers {
import language.implicitConversions
implicit def implicitMethod[A](a: => A) = new ToContainer[A] {
def wrappingMethod[E](e: E): Container[E, A] = Container(e, a)
}
implicit def implicitMethod2[E, A] (c: => Container[E, A])(implicit d:DummyImplicit): ToContainer[A] = new ToContainer[A] {
def wrappingMethod[EX](e: EX): Container[EX, A] = c.copy(e)
}
}
So that was the code.
The problem is that I need somehow bind type parameter EX
of function def wrappingMethod[EX]
to the parameter E
of def implicitMethod2[E, A]
.
After this something like this should work (and works):
scala> import ToContainers._
import ToContainers._
scala> val c1: Container[String, Int] = 1234.wrappingMethod("abc")
c1: Container[String,Int] = Container(abc,1234)
scala> val c2: Container[String, Int] = c1.wrappingMethod("XXX")
c2: Container[String,Int] = Container(XXX,1234)
... but this must yield compilation error, and don't :( (Take a look on types: c1 has [String, Int] and c3 has [Int,Int]. I want to prevent this.)
scala> val c3 = c1.wrappingMethod(0)
c3: Container[Int,Int] = Container(0,1234)
Any ideas great appreciated :)
BTW: I am using this version of scala:
Welcome to Scala version 2.10.0-M7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_07)
EDITED:
I've fiexed errors. Code is working now.
The sample code you provided does not work, so it's a bit difficult to provide a good answer. However, can't you just do something like:
implicit def implicitMethod2[E, A] (c: => Container[E, A])(implicit d:DummyImplicit): ToContainer[A] = new ToContainer[A] {
def wrappingMethod[E](e: E): Container[EX, A] = c.copy(e)
}
So simply replace the EX
type parameter with E
.
您需要将类型参数E
移至ToContainer
:
trait ToContainer[E, A]
def wrappingMethod(e: E): Container[E, A]
}
object ToContainers {
import language.implicitConversions
implicit def implicitMethod[E, A](a: => A) = new ToContainer[E, A] {
def wrappingMethod(e: E): Container[E, A] = Container(e, a)
}
implicit def implicitMethod2[E, A] (c: => Container[E, A])(implicit d:DummyImplicit): ToContainer[E, A] = new ToContainer[E, A] {
def wrappingMethod(e: E): Container[E, A] = c.copy(e)
}
}
链接地址: http://www.djcxy.com/p/51024.html