scala - 在隐式参数中,Scala: Bug

  显示原文与译文双语对照的内容
58 3

以下是我实际问题的简化版本:


class Z[T]


object E extends Enumeration {


 implicit val z = new Z[Value] 


 val X, Y = Value


}


implicit def f[T : Z] = (getter: T) => 0


implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0


def e: Option[E.Value] = null


val b: Int = e



这里操作有效,使用隐式转换为o ( e ) ( f ( e.z ) ) 。 但随着以下微小变化的发生:


implicit def f[T : Z] = (setter: T => Unit) => 0


implicit def o[T](v: Option[T])(implicit toInt: (T => Unit) => Int) = 0



尽管从原始代码中没有必要的差异,但是手动转换为 E.z ( ( e.z ) ( e ) ) 仍然有效。

我知道隐式参数的实现还没有完成,仍然存在许多还没有解决的问题。 如果是其中之一,我想向 Scala 贡献者报告。 我的问题是,这真的是一个 Bug? 如果是的话,如果是,我可以在哪里以及如何在以后修改 Bug 。

更新

Travis的回答 worked ! 另外,上面的代码是我原来问题的一种解决方法:


implicit object E extends Enumeration { val X, Y = Value }


implicit object F extends Enumeration { val X, Y = Value }


implicit def f[T <: Enumeration](getter: T#Value)(implicit e: T) = 0


implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0


val b: Int = Some[E.Value](null)



在这里代码中,情况是相反的: 它使用setter版本,但不使用简单的getter版本。 编译器表示,使用E 或者F 作为隐式参数是不可以思议的,但是使用F 实际上不会有意义。 我通过做类似的事情使它工作起来:


implicit def f[S <% T => T, T <: Enumeration](getter: T#Value)(implicit e: T) = 0



虽然我不知道这魔术背后的逻辑。

时间: 原作者:

113 3

你已经遇到了另一种变化:这是 Scala 推理系统类型的一种限制。

如果第1 种情况在第2 种情况下,编译器会解析 T,从普通的旧 E.ValueInt,而不是在第二种情况下,它希望从 E.Value => Unit ( 例如,Function1[E.Value, Unit] ) 到 Int 转换。

幸运的是,在this—just使用视图绑定的情况下,有一个简单的解决办法:


implicit def f[F <% T => Unit, T: Z] = (setter: F) => 0



这将按如下所示执行 desugar:


implicit def f[F, T](implicit st: F <: <(T => Unit), ev: Z[T]) = (setter: F) => 0



现在编译器希望从 E.Value => Unit 转换到 Int 时,它可以立即解析 fE.Value => Unit,然后将 T 解析为 E.Value

原作者:
...