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