@Jwvh 提供了更多基于编程的答案,但我想更深入地挖掘。
我当然感谢您尝试了解 Scala 中的工作原理,但是如果您真的想深入挖掘,恐怕您需要获得一些类别理论的基本知识,因为在 scala 中提升背后没有“想法” ” 但只是“提升背后的想法”
这也是为什么像“map”这样的函数会非常混乱的原因。从本质上讲,程序员被教导 map 等作为对集合的操作,而实际上它们是 Functors 和 Natural Transformations 附带的操作(这通常在 Category Theory 和 Haskell 中称为 fmap)。
在我继续之前,简短的回答是它是您提供的示例中的模式匹配,并且在 一些 中两者都是。 Map是专门针对case定义的,唯一的条件是它保持functoriality
注意:我不会在下面定义每个术语,因为我需要写一本书来建立以下一些定义,欢迎有兴趣的读者自己研究它们。按照类型应该可以有一些基本的了解
让我们将它们视为 Functor,其定义大致如下:
简而言之,我们将类型视为我们语言类别中的对象。这些类型(类型构造函数)之间的函数是该类别中类型之间的态射。这些转换的集合称为 Endo-Functors(将我们从 Scala 的类别中带回到 Scala 的类别中)。函子必须有一个多态的(实际上在范畴论中有一个完全不同的(额外的)定义)映射函数,它将获取一些对象 A,通过一些类型构造函数将其转换为对象 B。
implicit val option: Functor[Option] = new Functor[Option] {
override def map[A,B](optA: Option[A])(f: (A) => B): Option[B] = optA match{
case Some(a) => Some(f(a))
case _ => None
}
}
implicit val seq: Functor[Seq[_]] = new Functor[Seq[_]] {
override def map[A,B](sA: Seq[A])(f: (A) => B): Seq[B] = sA match{
case a :: tail => Seq(f(a), map(tail)(f))
case Nil => Nil
}
}
正如您在第二种情况下看到的那样,两者都有一点点(更多的是递归而不是迭代,但仍然如此)。
现在在我被互联网炸毁之前,我会说你不能在 Scala 中的 Seq 上进行模式匹配。它在这里工作是因为默认的 Seq 也是一个列表。我只是提供了这个例子,因为它更容易理解。基本定义与此类似。
现在等一下。如果您查看这些类型,您会发现它们还定义了 flatMap。这意味着它们比普通的 Functor 更特别。他们是单子。因此,除了满足功能性之外,它们还遵守一元法则。
原来 Monad 在核心 scala 中具有不同的含义,更多内容请参见:What exactly makes Option a monad in Scala?
但是又非常非常短,这意味着我们现在处于一个类别中,我们之前类别中的内函子是对象,它们之间的映射是态射(自然变换),这稍微更准确,因为如果你考虑一下当您采用类型并对其进行转换时,您会采用(继承)它的所有内部类型构造函数(2-cell 或内部态射),您不仅会采用这种类型的唯一概念而没有它的功能。
implicit val optionMonad: Monad[Option] = new Monad[Option] {
override def flatMap[A, B](optA: Option[A])(f: (A) => Option[B]): Option[B] = optA match{
case Some(a) => f(a)
case _ => None
}
def pure[A](a: A): Option[A] = Some(a)
//You can define map using pure and flatmap
}
implicit val seqMonad: Monad[Seq[_]] = new Monad[Seq[_]] {
override def flatMap[A, B](sA: Seq[A])(f: (A) => Seq[B]): Seq[B] = sA match{
case x :: xs => f(a).append(flatMap(tail)(f))
case Nil => Nil
}
override def pure[A](a: A): Seq[A] = Seq(a)
//Same warning as above, also you can implement map with the above 2 funcs
}
您始终可以依靠的一件事是 map 具有模式匹配(或某些 if 语句)。为什么?
为了满足恒等律,我们需要某种“基本情况”,一个单元对象,并且在许多情况下(例如列表),这些类型将是我们所说的产品或副产品。
希望这不会让您更加困惑。我希望我能深入了解这方面的每一个细节,但它只需要几页,我强烈建议进入类别以充分了解这些来自何处。