Scala绑定性状的类型参数,具有函数的类型参数



很难用几个单词来解释问题,因此我准备了代码的派对来提出问题。

让我们开发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)
        }
      }
    

这就是代码。

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

之后,类似的事情应该起作用(并且有效):

        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热点(TM)64位服务器VM,Java 1.7.0_07)

编辑:

我已经错误了。代码现在正在工作。

您提供的示例代码不起作用,因此很难提供一个好的答案。但是,您不能只做以下操作:

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

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

最新更新