我正在学习Scala和函数式编程世界的新手。我看到大多数方法,例如foldRight
,map
,filter
,reduce
……始终可以由foldLeft
编写(使用tails递归由foldLeft编写为foldRight)。
例如:
def map[A, B](l: List[A])(f: A => B): List[B] =
foldRight(l, Nil: List[B])((x, xs) => Cons(f(x), xs))
def reverse[A](l: List[A]): List[A] =
foldLeft(l, l)((xs, x) => Cons(x, xs))
def foldRight[A, B](l: List[A], z: B)(f: (A, B) => B): B =
foldLeft(reverse(l), z)((xs, x) => f(x, xs))
在进入函数式编程世界之前,我认为
map
和reduce
是函数式编程的两种基本方法。从这两种方法中,我可以构建更复杂的方法。但是基于上面的示例,我认为foldLeft
应该基于所有功能方法,例如map,filter,...在函数式编程世界中,这是真的吗?
谢谢
最佳答案
通常,不,foldLeft
并不是所有其他方法的“父亲”,因为除了List
之外,还有许多其他集合。例如,您不能通过Stream.map
实现Stream.foldLeft
,因为foldLeft
会进行完整遍历,但是map
不应由于其惰性而遍历该流(它可能是无限的)。
至于List
,您基本上是正确的。但是,如果通过foldLeft
实现,则某些方法效率极低。考虑list.drop(1)
。它应该只返回列表的末尾,但是foldLeft
将进行完整遍历。