我正在学习Scala和函数式编程世界的新手。我看到大多数方法,例如foldRightmapfilterreduce……始终可以由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))

在进入函数式编程世界之前,我认为mapreduce是函数式编程的两种基本方法。从这两种方法中,我可以构建更复杂的方法。但是基于上面的示例,我认为foldLeft应该基于所有功能方法,例如map,filter,...

在函数式编程世界中,这是真的吗?

谢谢

最佳答案

通常,不,foldLeft并不是所有其他方法的“父亲”,因为除了List之外,还有许多其他集合。例如,您不能通过Stream.map实现Stream.foldLeft,因为foldLeft会进行完整遍历,但是map不应由于其惰性而遍历该流(它可能是无限的)。

至于List,您基本上是正确的。但是,如果通过foldLeft实现,则某些方法效率极低。考虑list.drop(1)。它应该只返回列表的末尾,但是foldLeft将进行完整遍历。

10-08 12:35