【问题标题】:None type in Priority queue scala优先队列scala中的无类型
【发布时间】:2017-08-02 10:02:42
【问题描述】:

我正在使用优先级队列来订购名为 TreeNodeWithCostAndHeuristic 的案例类

  case class TreeNodeWithCostAndHeuristic[S,A](parent:Option[TreeNodeWithCostAndHeuristic[S,A]],
                                           action: Option[A],
                                           state: S,
                                           cost: Double,
                                           estimatedRemainingCost: Double)

这个优先级队列是在一个函数内部创建的,该函数使用它的参数来设置初始状态,而其他值必须保持为 None 或 0

  def HeuristicGraphSearch[S,A](problem: ProblemWithCostAndHeuristic[S,A]) = {
    val root = TreeNodeWithCostAndHeuristic(parent = None,action=None,state=problem.initialState,cost = 0.0, estimatedRemainingCost = 0.0)
    val frontier : mutable.PriorityQueue[TreeNodeWithCostAndHeuristic[S,A]] = mutable.PriorityQueue.empty[TreeNodeWithCostAndHeuristic[S,A]]
    frontier.enqueue(root)

但是,由于没有父项和操作,我得到预期类型 TreeNodeWithCostAndHeuristic[S,A] 与我尝试排队的 TreeNodeWithCostAndHeuristic[S,Nothing] 之间的不匹配。

据我所知,Nothing 是 Option 的子类型,在我的案例类中,父类和操作都是选项。为什么会出现不匹配的情况?

【问题讨论】:

    标签: scala functional-programming


    【解决方案1】:

    这与 Scala 编译器推断类型的方式有关。简短的回答是通过在构造案例类时显式声明类型来简单地帮助它:

    val root = TreeNodeWithCostAndHeuristic[S, A](parent = None,action=None,state=problem.initialState,cost = 0.0, estimatedRemainingCost = 0.0)
    

    TreeNodeWithCostAndHeuristic[S, Nothing] 不被视为TreeNodeWithCostAndHeuristic[S, A] 的有效替代品的原因是因为它不是它的子类;要成为一个,它必须在类型 A 中是协变的。如果某些 Foo[A] 在其类型 A 中是协变的,那么只有以下情况成立:Foo[S] <: Foo[A] 用于任何 S,它是 A 的子类。

    【讨论】:

      【解决方案2】:

      除了sloucs的回答,还可以使用type ascription来帮助编译:

      val root = TreeNodeWithCostAndHeuristic(
          parent = None: Option[TreeNodeWithCostAndHeuristic[S, A]],
          action = None: Option[A],
          state = problem.initialState,
          cost = 0.0,
          estimatedRemainingCost = 0.0)
      

      编译器抱怨的原因是它无法保证None.type Option[TreeNodeWithCostAndHeuristic[S, A]]Option[A],因此它“退出”并推断出@987654326 @,是所有类型中最底层的类型。

      @Dima 还建议使用Option.empty[A]

      val root = TreeNodeWithCostAndHeuristic(
          parent = Option.empty,
          action = Option.empty[A],
          state = problem.initialState,
          cost = 0.0,
          estimatedRemainingCost = 0.0)
      

      【讨论】:

      • 我宁愿使用 Option.empty - 看起来比在此处键入 ascription 更好:action = Option.empty[A]
      • @Dima 你可能是对的,我不确定我更喜欢哪一个。我将两者都添加。
      猜你喜欢
      • 1970-01-01
      • 2013-03-25
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 1970-01-01
      相关资源
      最近更新 更多