Scala类型不匹配,无法解析符号A,模式类型与预期类型不兼容

Scala类型不匹配,无法解析符号A,模式类型与预期类型不兼容,scala,Scala,我正在编写Scala函数式编程第5章中的流类,我知道解决方案是在线的,但这对我没有帮助。在上一章编写List类时,我遇到了同样的问题 我非常沮丧,实际上我将粘贴的解决方案复制到了我的Scala工作表中,但仍然是同一个问题 我想可能是因为名字已经有了一个列表和流,这样命名似乎不是一个明智的主意,所以我改变了它,没有帮助 也许这与Intellij有关我在用Intellij的想法,我在做Scala工作表上的练习。但是我找不到任何关于IDE的问题 以下是我到目前为止的情况: sealed trait S

我正在编写Scala函数式编程第5章中的流类,我知道解决方案是在线的,但这对我没有帮助。在上一章编写List类时,我遇到了同样的问题

我非常沮丧,实际上我将粘贴的解决方案复制到了我的Scala工作表中,但仍然是同一个问题

我想可能是因为名字已经有了一个列表和流,这样命名似乎不是一个明智的主意,所以我改变了它,没有帮助

也许这与Intellij有关我在用Intellij的想法,我在做Scala工作表上的练习。但是我找不到任何关于IDE的问题

以下是我到目前为止的情况:

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

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

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

  def headOption: Option[A] = this match {
    case Empty => None
    case Cons(h,t) => Some(h())
  }

  def toList: List[A] = {
    @annotation.tailrec
    def go(s: StreamRED[A], acc: List[A]): List[A] = s match {
      case Cons(h,t) => go(t(), h() :: acc)
      case _ => acc
    }
    go(this, List()).reverse
  }
}
我得到以下错误:

无法解析headOption方法和列表[A]中选项[A]中A上的符号A以及toList中的StreamRED[A]

类型不匹配。必需:StreamRED[Any],在this in toList上找到:StreamRED.type

模式类型与预期类型不兼容,在“头中为空”选项上找到:Empty.type,必需:StreamRED.type

Scala新手,IntelliJ新手,静态类型语言新手,FP新手。非常感谢对优秀阅读材料的任何解释和建议。

在StreamRED的伴生对象中无法定义toList和headOption这两个函数

如果您直接在trait中定义它们,那么它会起作用:

密封红色[+A]{ def headOption:选项[A]=此匹配项{ 大小写为空=>无 case Consh,t=>Someh } def toList:列表[A]={ @注释.tailrec def gos:StreamRED[A],acc:List[A]:List[A]=s匹配{ 案例Consh,t=>got,h::acc 案例=>acc } 明白了,列表,反向 } } case对象为空扩展StreamRED[无] 案例类别Cons[+A]h:=>A,t:=>StreamRED[A]扩展StreamRED[A] 对象流{ def cons[A]hd:=>A,tl:=>StreamRED[A]:StreamRED[A]={ 延迟val head=hd 延迟val tail=tl Cons=>头部,=>尾部 } def empty[A]:StreamRED[A]=空 def应用[A]为:A*:流化[A]= 如果as.isEmpty为空,否则contas.head、applyas.tail:_* } 警告一句:在我看来,这种模式匹配是一种糟糕的做法。你很清楚这是什么。改为在空和Cons中实现函数

改为这样做:

密封红色[+A]{ def头选项:选项[A] def toList:列表[A] } case对象为空扩展StreamRED[无]{ def headOption:选项[无]=无 def toList:列表[无]=列表 } 案例类别Cons[+A]h:=>A,t:=>StreamRED[A]扩展StreamRED[A]{ def headOption:选项[A]=Someh def toList:List[A]=h+:t.toList } 对象流{ def cons[A]hd:=>A,tl:=>StreamRED[A]:StreamRED[A]={ 延迟val head=hd 延迟val tail=tl Cons=>头部,=>尾部 } def empty[A]:StreamRED[A]=空 def应用[A]为:A*:流化[A]= 如果as.isEmpty为空,否则contas.head、applyas.tail:_* }
警告一句:在这种情况下进行模式匹配是不好的做法,真的,为什么?我可以同意,由于动态调度,重写方法的性能可能会更高,但既然自模式匹配没有问题,我甚至可以说这是ADTs中方法的常见实现。非常感谢!有什么建议可以让我知道什么是去哪里的吗?这是我最大的问题,比如我什么时候做一个trait,什么时候做一个类,什么时候做一个对象,什么时候做一个单例对象,什么时候组合它们。唯一清楚的是案例类,喜欢它!有很多有用的指南,但它非常简单:对象是静态的,类似于单例,case类是具有默认构造函数和模式匹配功能的数据定义,trait是需要实现的接口,尽管它们可以包含实现,类是为所有其他对象而设的。@LuisMiguelMejíaSuárez你是指代数数据类型还是抽象数据类型?@LuisMiguelMejíaSuárez我明白了。那可能只是我个人的口味。