pawel.panasewicz
pawel.panasewicz

Reputation: 1833

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

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.

Upvotes: 1

Views: 1030

Answers (2)

Ptharien's Flame
Ptharien's Flame

Reputation: 3246

You need to move the type parameter E up to 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)

  }

}

Upvotes: 0

Emil L
Emil L

Reputation: 21091

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.

Upvotes: 2

Related Questions