【问题标题】:scala bind type parameter of trait with type parameter of functionscala将特征的类型参数与函数的类型参数绑定
【发布时间】:2012-10-17 16:47:42
【问题描述】:

很难用几句话来解释问题,所以我准备了一些代码来提出问题。

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

任何想法都非常感谢:)

顺便说一句:我正在使用这个版本的 scala:

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

已编辑:

我已经修复了错误。代码正在运行。

【问题讨论】:

  • 请提供实际编译的代码(当然你的问题除外)
  • Kim,现在可以编译代码示例。

标签: scala generics implicit-conversion implicit scalaz


【解决方案1】:

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

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

【讨论】:

  • 嗨,Emil,您的解决方案不能解决我的问题。即使我用 E 替换 EX,新 E 仍然不会引用 E。这在第三个示例中有所描述,它不应​​该编译。
【解决方案2】:

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

  }

}

【讨论】:

    猜你喜欢
    • 2018-04-11
    • 1970-01-01
    • 2022-12-11
    • 2015-02-22
    • 2012-07-10
    • 2023-04-01
    • 1970-01-01
    • 2016-07-04
    • 2011-11-13
    相关资源
    最近更新 更多