【问题标题】:Type Error for Context Bounding with Priority Implicits具有优先级隐式的上下文边界的类型错误
【发布时间】:2020-11-05 11:02:31
【问题描述】:

我有以下问题,我对发生的事情感到困惑:

  1. 我有一个隐式定义的优先级
  2. 我使用此优先级隐式来施加上下文限制
  3. 我声明了一个带有默认字段的案例类,该字段的值被上下文绑定所覆盖
  4. 我仍然收到类型错误

反映我正在处理的实际代码的最小工作示例。我基本上需要在我的代码的其他部分隐含优先级:

    // priority implicits
    sealed trait Stringifier[T] {
      def stringify(lst: List[T]): String
    }
    
    trait Int_Stringifier {
      implicit object IntStringifier {
        def stringify(lst: List[Int]): String = lst.toString()
      }
    }
    
    object Double_Stringifier extends Int_Stringifier {
      implicit object DoubleStringifier extends Stringifier[Double] {
        def stringify(lst: List[Double]): String = lst.toString()
      }
    }
    
    object Example extends App {
    
      trait Animal[T0] {
        def incrementAge(): Animal[T0]
      }
    
      case class Dog[T0: Stringifier]
      (age: Int = 0, locations: List[T0] = List(1, 2, 3)) extends Animal[String] {
        def incrementAge(): Dog[T0] = this.copy(age = age + 1)
      }
    }
 val t = Dog(age = 100)

我收到类型不匹配错误:

required List[T0]

found List[Int]

这里发生了什么?我推断,由于我在边界内创建默认参数,因此类型应该匹配。我是否遗漏了一些技巧来完成这项工作?

【问题讨论】:

  • @finite_diffidence 你的代码不是MCRE 因为它编译了scastie.scala-lang.org/W4jDvvnjSIu1JwSvw3yJrA 如何重现你的编译错误?
  • 道歉 Dmytro,似乎我的 IDE 在屏幕上显示错误,我在示例中添加了一行,但它引发了关于未找到隐式的不同错误 - 我认为该错误与无法提供证据。
  • @user 如果有人希望位置是 List[String] 怎么办? 这将是调用站点上的编译错误,而不是定义站点上的编译错误。
  • @user 您也许可以使用implicitly[List[T0]] 并提供List[Int] 等的隐式值。List[...] 这样的标准类型的隐式确实是个坏主意.
  • @DmytroMitin 我并不是说implicitly[List[T0]] 是一个好的解决方案,只是你可以将它用作创可贴。不过,我不知道您可以提供这样的默认参数。我现在删除了我的评论。

标签: scala generics implicit-conversion context-bound


【解决方案1】:

不清楚如何重现你的编译错误

required List[T0]

found List[Int]

你添加的代码

val t = Dog(age = 100)

产生不同的错误

Error: could not find implicit value for evidence parameter of type App.Stringifier[Int]
Error occurred in an application involving default arguments.
    val t = Dog(age = 100)

这是因为你错过了extends Stringifier[Int]import Double_Stringifier._

trait Int_Stringifier {
  implicit object IntStringifier extends Stringifier[Int] {
    def stringify(lst: List[Int]): String = lst.toString()
  }
}

import Double_Stringifier._

val t = Dog(age = 100) // compiles

【讨论】:

  • 感谢@Dmytro,我将不得不返回我的代码并重新访问 - 当我进行更改时,IDE 仍然在我这边显示错误,但代码确实可以编译。我认为这可能与我的 IntelliJ 有问题,但我会看看。
  • @finite_diffidence 实际上对我来说 IntelliJ 2020.1.3 也显示类型不匹配。这是编译错误的错误报告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 2020-10-03
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
  • 2020-07-22
相关资源
最近更新 更多