list -::[Int] 与 List[Int] 相同吗?

标签 list scala cons

scala> val w = new ::[Int](4,Nil)
w: scala.collection.immutable.::[Int] = List(4)

scala> val x = List[Int](4)
x: List[Int] = List(4)

这两个表达式有什么区别? ::[Int](4)List[int] 的实例吗,因为 ::[Int](4)List[Int](4) 产量List(4)?

最佳答案

::[T]代数数据类型构造函数之一 List[T] 。另一个是Nil。考虑以下inductive definition 列表

sealed trait List[+T]
case object Nil extends List[Nothing] 
case class ::[T](head: T, tail: List[T]) extends List[T]

:: 可能看起来有点奇怪,因为它纯粹是符号名称,在其他语言中有时被称为 Cons 。构造函数是创建 List[T] 类型的的方法,这里有一些

Nil
::(1, Nil)
::(2, ::(1, Nil))
::(42, ::(2, ::(1, Nil)))

这些值具有归纳性质,具有一个显着的特性,即每当我们拥有一个值时,我们总是知道如何构造以下值。换句话说,归纳值意味着归纳值。例如,两者

::(2, ::(1, Nil))

::(51, ::(1, Nil))

通过构造函数 ::[Int] 的力量实现 ::(1, Nil) 的含义。

Is ::[Int] the same as List[Int]?

因为 Scala 使用 form of inheritance 实现代数数据类型,确实存在is-a-subtype-of关系

implicitly[::[Int] <:< List[Int]] // ok!

虽然不存在等于关系

implicitly[::[Int] =:= List[Int]] // error!

但是,在我看来,这些子类型关系不是代数数据类型的重点,在 Scala 中是偶然的。相反,构造函数 ::[T] 和正在构造其值的类型 List[T] 之间的关系更类似于函数<之间的关系/em> 和一个类型

Is new ::[Int](4, Nil) the same as List[Int](4)?

它们都计算出相同的值,例如以下遍

assert(new ::[Int](4, Nil) == List[Int](4))

但是我们得出这个值的方式却截然不同。在前一种情况下,我们直接使用 List[Int] ADT 的构造函数,而在后一种情况下,我们实际上是在 companion 上调用 apply 方法 trait List[T]

的对象
List.apply[Int](4)

其中 apply 定义为

def apply[A](xs: A*): List[A] = xs.toList

现在在实践中我们很少需要考虑这些事情。通常我们只是简单地写一些像

List(4, 2, 42)

然后就完成了。 “低级”构造函数::有时会在模式匹配期间显露出来,这是一种解构ADT的方式,例如,这里是递归获取列表中元素总和的实现

def sum(l: List[Int]): Int = {
  l match {
    case Nil => 0
    case head :: tail => head + sum(tail)
  }
}

sum(List(1, 2, 42)) 
// res1: Int = 45

关于list -::[Int] 与 List[Int] 相同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59792287/

相关文章:

json - 使用 Argonaut 进行 Scalaz 验证

scala - 将参数标记为隐含在方法中

Scala 从列表中生成唯一的对

linq - 根据另一个列表从列表条件中删除某些元素

Python:带有 cons、car 和 cdr 的函数式编程

data-structures - 不能在 Clojure 的库级别有效地实现 cons 单元吗?

list - 将函数应用于自定义数据结构列表

python - 从数组中删除项目

r - 提取列表 R 中每个向量中的多个元素