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

    上一篇: 在scala中的父特征中的一个子特征的类型

    下一篇: scala绑定特征的类型参数与函数的类型参数