【问题标题】:Issue with pattern matching in scala: "error: constructor cannot be instantiated to expected type"scala 中的模式匹配问题:“错误:构造函数无法实例化为预期类型”
【发布时间】:2018-12-05 20:02:18
【问题描述】:

我正在尝试在 trait 中定义一个 toList 方法,如下所示:

sealed trait Stream[+A] {
  def toList: List[A] = this match {
      case Empty => List()
      case Cons(h, t) => h()::t().toList()
  }
}

case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]   


object Stream {
  def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {    
    lazy val head = hd  
    lazy val tail = tl
    Cons(() => head, () => tail)
  }
  def empty[A]: Stream[A] = Empty   

  def apply[A](as: A*): Stream[A] = 
    if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*))
}

我收到以下编译错误:

stream.scala:16: error: pattern type is incompatible with expected type;
 found   : Empty.type
 required: Stream[A]
      case Empty => List()
               ^
stream.scala:17: error: constructor cannot be instantiated to expected type;
 found   : Cons[A(in class Cons)]
 required: Stream[A(in trait Stream)]
      case Cons(h, t) => h()::t().toList()
               ^

有人可以建议吗?

【问题讨论】:

  • 为了您的信息,我从 scala REPL 加载源文件如下:scala> :load stream.scala
  • .toList 之后的这个() 不属于那里,但除此之外,它似乎编译得很好?至少,它可以在 2.12.5 - 2.12.7 版本中编译。

标签: scala pattern-matching


【解决方案1】:

您看到的错误来自 REPL。 REPL 中的每条完整语句都封装在一个对象中,以便它可以生成和报告中间值:res0res1 等。

当你 :load 文件时,就好像你已经分别输入了每一行,但是如果你复制/粘贴 :pa,代码到 REPL 中它可以工作(在你修复 () 问题之后)。

另一种选择是将所有代码包装到外部object 中。然后当你:load 文件时,它将被编译为一个单元而不是单独的对象和类。

【讨论】:

  • 非常感谢您的回复!
猜你喜欢
  • 2019-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-06
  • 1970-01-01
  • 2019-09-16
  • 1970-01-01
相关资源
最近更新 更多