scala绑定类型参数的trait与函数的类型参数

时间:2012-10-17 16:47:43

标签: scala generics implicit-conversion implicit scalaz

很难用很少的单词来解释问题,所以我准备了一些代码来提出问题。

让我们开发类型为Container[T1,T2]的容器,并指示包装该容器中的任何值。如果值为Container[T1,T2]包装的类型,则应返回相同的类型。更多的包装方法应该采用T1类型的参数(与容器中的相同),并且使用具有替换T1值的容器。 解决方案必须符合泛型和隐含方式。

听起来有点混乱,让我们读一下代码:)

  • 容器:

    case class Container[T1, T2](t1: T1, t2: T2)
    
  • 使用包装方法的特性:

      trait ToContainer[A] {
        def wrappingMethod[E](e: E): Container[E, A]
      }
    
  • 带有含义的对象:

      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)
        }
      }
    

这就是代码。

问题是我需要以某种方式将函数EX的类型参数def wrappingMethod[EX]绑定到E的参数def implicitMethod2[E, A]

在这之后,这样的事情应该起作用(并起作用):

        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)

...但这必须产生编译错误,而不是 :(   (看看类型:c1有[String,Int],c3有[Int,Int]。我想阻止它。)

        scala>  val c3 = c1.wrappingMethod(0)
        c3: Container[Int,Int] = Container(0,1234)

非常感谢任何想法:)

BTW:我正在使用这个版本的scala:

欢迎使用Scala版本2.10.0-M7(Java HotSpot(TM)64位服务器VM,Java 1.7.0_07)

编辑:

我犯了错误。代码现在正在运作。

2 个答案:

答案 0 :(得分:2)

您提供的示例代码不起作用,因此提供一个好的答案有点困难。但是,你不能只做这样的事情:

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)
}

只需将EX类型参数替换为E

答案 1 :(得分:0)

您需要将类型参数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)

  }

}