[英]Scala generic: type mismatch
In the purpose of learning, I would like to understand how "::" class is working. 在学习的目的,我想了解“::”类是如何工作的。
So I decided to create my own but instead of calling it "::" I want to call it ":++:" 所以我决定创建自己的,但不是称它为“::”我想称之为“:++:”
From List.scala source code, the University of Helsinki and Programming In Scala 2nd edition (Chapter 22) I should write: 从List.scala源代码, 赫尔辛基大学和Scala编程第2版(第22章)我应该写:
abstract class List[+A] {
def isEmpty: Boolean
def head: A
def tail: List[A]
}
final case class :++:[A](head: A, tail: List[A]) extends List[A] {
override def isEmpty: Boolean = false
}
I can create "::" objects 我可以创建“::”对象
new ::(1, List(2)) 新::( 1,清单(2))
But I can't create my ":++:" objects: 但我无法创建我的“:++:”对象:
new :++:(1, List(2))
<console>:12: error: type mismatch;
found : List[Int]
required: List[?]
new :++:(1, List(2))
Where is my mistake? 我的错误在哪里?
Annotating the :++:
type parameter gives you a hint: 注释:++:
type参数为您提供了一个提示:
scala> new :++:[Int](1, List(2))
<console>:11: error: type mismatch;
found : scala.collection.immutable.scala.collection.immutable.List[Int]
required: List(in object $iw)[Int]
new :++:[Int](1, List(2))
^
The :++:
constructor expects one of your custom List[A]
instances, but you give it a normal Scala List(1)
. :++:
构造函数需要一个自定义List[A]
实例,但是你给它一个普通的Scala List(1)
。
But you currently have no way to create an instance of your list (other than having a null
tail). 但是你目前无法创建列表的实例(除了有一个null
尾)。 If you add an equivalent of Nil
, then you are all good: 如果你添加相当于Nil
,那么你们都很好:
case object Empty extends List[Nothing] {
def head = ???
def isEmpty = true
def tail = ???
}
And then you can create a :++:
: 然后你可以创建一个:++:
::
scala> val a = new :++:[Int](1, Empty)
a: :++:[Int] = :++:(1,Empty)
scala> val b = new :++:(2, a)
b: :++:[Int] = :++:(2,:++:(1,Empty))
In addition to gourlaysama's answer which explains why your definition is shadowed by the built-in List
, I'd like to drop a few hints. 除了gourlaysama的答案 ,它解释了为什么你的定义被内置List
所掩盖,我想提一些提示。
Empty
or CNil
case object for the 'empty' list. 根据上面的答案,您还应该为“空”列表添加Empty
或CNil
案例对象。 List
, similar to one below: 如果再次检查源,您将在内置List
找到'cons'方法,类似于下面的方法: sealed abstract class ConsList[+A] {
(...)
def :++:[B >: A](x : B) : ConsList[B] = new :++:(x, this)
}
It allows you to create the list using infix notation: 它允许您使用中缀表示法创建列表:
val b = 2 :++: 4 :++: 7 :++: CNil
And finally, you can create a companion object for easier list creation: 最后,您可以创建一个伴随对象,以便更轻松地创建列表:
object ConsList {
def apply[A](xs : A*) = {
xs.foldRight(CNil : ConsList[A])((el, l) => el :++: l)
}
}
Which means that you can now create val c = ConsList(2, 4, 7)
which will be equivalent to b
above, and also equivalent to :++:(2, :++:(4, :++:(7, CNil)))
这意味着你现在可以创建val c = ConsList(2, 4, 7)
,它等同于上面的b
,也相当于:++:(2, :++:(4, :++:(7, CNil)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.