斯卡拉未能推断出正确的类型参数

斯卡拉未能推断出正确的类型参数

本文介绍了斯卡拉未能推断出正确的类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景信息:我目前正试图建立一个包含几种不同搜索算法的通用图库(我已经开始使用Dijkstra的)。我已经设置了几个特征来表示可以在某些类型的图表中找到的方法(例如加权,定向):

 特征GraphOps [V,E] {...} 
trait WeightedGraphOps [V,E]扩展GraphOps [V,E] {...}
特性DirectedGraphOps [V,E] V,E] {...}
对象GraphOps {
def Dijkstra [V,E,G }

其他地方,我有一堂课作为我想运行Dijkstra算法的加权有向图的具体实现:

  class GraphMap [T](。 ..)
使用WeightedGraphOps [Position,Edge]与DirectedGraphOps [Position,Edge] {...}
c $ c>

但是当我尝试测试时:

  val graph = new GraphMap [Int](...)
val(dist,prev)= GraphOps.Dijkstra(graph,Position(0,0))

问题:编译期间出现以下错误: error:推断类型参数[com.dylan.data.Position,Nothing,com.dylan.data.GraphMap [Int]]不符合方法Dijkstra的类型参数边界[V,E,G<:com.dylan.data.WeightedGraphOps [V ,E] with com.dylan.data.DirectedGraphOps [V,E]]

我花了很长时间才注意到它推断出我的边缘( E )类型为 Nothing ,但我不明白为什么它没有成功推断它应该是 Edge 。为什么它不能推断这个类型参数,我该如何解决它?



我尝试着做下面的事情,并且让它起作用,但这对于一种应该是一种便利方法的东西来说似乎非常不方便:

 类型有帮助= WeightedGraphOps [位置,边缘]与DirectedGraphOps [位置,边缘] 
val(dist,prev)= GraphOps.Dijkstra [位置,边缘,有帮助](图形,位置(0,0))


解决方案

Daniel可能是对的,现有的Scala类型推理器需要更直接的找出 E 必须是 Edge 的信息。此外,我的理解是,类型推断有意未被指定,以供将来改进。



无论如何,我认为您可以采取另一种方法来设计您的设计解决类型推断问题:使用类型成员而不是参数。我已经用下面的自包含代码说明了我的意思。关键的想法是类型 E V 成为 GraphOps type,但它们仍然可以通过使用 type refinement 来表现为类型参数,如 Dijkstra 方法。

  trait GraphOps {type E;类型V} 
trait WeightedGraphOps extends GraphOps {}
trait DirectedGraphOps extends GraphOps {}
object GraphOps {
def Dijkstra [V0,G with(DirectedGraphOps {type V = V0})]
(graph:G,start:V0)= {}
}

case class Position x:Int,y:Int)
case class Edge()

case class GraphMap [T]()将DirectedGraphOps扩展为WeightedGraphOps {
type E = Edge
类型V =位置
}

对象测试{
val graph = new GraphMap [Int]()
GraphOps.Dijkstra(graph,Position(0,0) )
}

编辑

Edit2 Ignore the above paragraph. As Dylan mentioned in the comments, for this diamond inheritance situation, Scala nicely ensures the consistency of the type E. For example, the following compiles fine:

trait GraphOps { type E; type V }
trait WeightedGraphOps extends GraphOps { def f(e: E) }
trait DirectedGraphOps extends GraphOps { def e: E }
object GraphOps{
  def Dijkstra[V0, G <: (WeightedGraphOps{type V = V0}) with (DirectedGraphOps{type V = V0})] (graph:G, start:V0) = {
    graph.f(graph.e)
  }
}

这篇关于斯卡拉未能推断出正确的类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 07:22