【问题标题】:Implicit parameters break type inference or inference does not suffice for their resolution?隐式参数中断类型推断或推断不足以解决它们?
【发布时间】:2014-12-14 09:39:27
【问题描述】:

在我添加隐式排序证据之前,类型推断在此示例中运行良好。类型推断规则(从左到右和跨参数列表)似乎得到了满足,但是关于隐式的某些东西会破坏它。

case class Insert[I, O : Ordering](arg: I)
def execute[I,O](req: Insert[I,O]): O = null.asInstanceOf[O]
val result: Int = execute(Insert("test"))

Error:(5, 39) diverging implicit expansion for type Ordering[O]
starting with method Tuple9 in object Ordering
lazy val result: Int = execute(Insert("test"));}
                                     ^

这编译和工作正常:

case class Insert[I, O](arg: I)
def execute[I,O](req: Insert[I,O]): O = null.asInstanceOf[O]
val result: Int = execute(Insert("test"))

因此,任何一种类型推断都不足以进行隐式解析,或者隐式解析会破坏类型推断。

我猜O 类型是推断出来的,但是当隐式解析发生时,它认为它是无,换句话说,它认为它好像我没有在val result: Int 中指定Int。是bug吗?

【问题讨论】:

    标签: scala type-inference typeclass implicits


    【解决方案1】:

    这里的问题是 scala 无法推断出 O 类型,因为它在 Insert 中不存在

    // I is in the parameter list but there is no O to be found
    case class Insert[I, O](arg: I)(implicit evidence: Ordering[O]) 
    

    这使得编译器别无选择,只能将O 推断为Nothing。然后创建Insert 的实例将无法编译。

    scala> val i = Insert(3)
    <console>:9: error: diverging implicit expansion for type Ordering[O]
    starting with method Tuple9 in object Ordering
       val i = Insert(3)
    

    diverging implicit expansion 错误是 scala 试图找到适用于这种情况的隐式并陷入循环。这是一条红鲱鱼。

    【讨论】:

    • 恕我直言,这里的重要时刻是发生在这里的类型构造val result: Int = execute(Insert("test")),之前的任何东西都只是一个类型参数声明,恕我直言,@ 987654331@ 不存在于@ 中并不重要987654332@作为参数,这里只有类型构造很重要,以及当时是否推断出Int类型,因为我明确指定了它,所以应该解析隐式参数
    • 我的意思是,O 永远不会像您认为的那样推断为 IntO 被推断为 Nothing 并且您的方法最终返回类型为 Nothing
    • 我明白你的意思,所以如果类型推断从val i: IntexecuteInsert 转换,我认为它应该在方法调用中起作用,这是一个问题,对吧?又名“从左到右,跨参数列表”,问题是它是否也适用于方法调用:-)
    • 我希望你明白我的意思,因为这个类定义编译得很好case class Insert[I, O](arg: I)(implicit evidence: Ordering[O]),直到你尝试在val result: Int = execute(Insert("test"))这里实例化类型参数,其中Int类型是/应该被实际推断出
    • 下面是有和没有隐式参数的程序的类型检查内部的比较:rawgit.com/retronym/22260bca2087f21cfd41/raw/out.html 没有隐式参数,未确定的类型变量O 被推断为Nothing,以便将execute 的结果类型调整为声明的类型Int。使用隐式参数,对Ord[O] 的隐式搜索无法解析唯一匹配的隐式,并且在考虑Int 之前类型检查失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多