以前,Nicolas Rinaudo回答了我关于Scala 列表的问题foldRight总是使用foldLeft?
目前正在研究Haskell,我的理解是,在(prepend)可以使用(append)的情况下foldRight应该优先考虑.foldLeft::++
据我所知,原因是性能 - 前者发生在O(1),即在前面添加一个项目 - 恒定时间.而后者需要O(N),即遍历整个列表并添加项目.
在Scala中,因为foldLeft是在以下方面实现的foldRight,不使用的好处:+在++与foldRight连问题,因为foldRight被逆转,然后foldLeft'd?
例如,考虑这个简单的fold..操作,只需按顺序返回列表的元素.
foldLeft折叠每个元素,将每个项目添加到列表中:+.
scala> List("foo", "bar").foldLeft(List[String]()) {
(acc, elem) => acc :+ elem }
res9: List[String] = List(foo, bar)
Run Code Online (Sandbox Code Playgroud)
foldRight::在每个项目上使用运算符执行foldLeft ,然后反转.
scala> List("foo", "bar").foldRight(List[String]()) {
(elem, acc) => elem :: acc }
res10: List[String] = List(foo, bar)
Run Code Online (Sandbox Code Playgroud)
实际上,在Scala中哪个foldLeft …
我听说foldLeft在大多数操作中效率更高,但Scala School(来自Twitter)给出了以下示例.有人可以分析它的效率吗?我们应该使用foldLeft实现相同的操作吗?
val numbers = List(1,2,3,4,5,...10)
def ourMap(numbers: List[Int], fn: Int => Int): List[Int] = {
numbers.foldRight(List[Int]()) { (x: Int, xs: List[Int]) =>
fn(x) :: xs
}
}
scala> ourMap(numbers, timesTwo(_))
res0: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
Run Code Online (Sandbox Code Playgroud) 在另一个练习中实现Monad.sequence()从斯卡拉函数式编程,我的回答来自官方不同/知到是正确的答案:
def序列[A](lma:List [F [A]]):F [List [A]]
官方:
def sequence[A](lma: List[F[A]]): F[List[A]] =
lma.foldRight(unit(List[A]()))((ma, mla) => map2(ma, mla)(_ :: _))
Run Code Online (Sandbox Code Playgroud)
矿:
def sequence[A](lma: List[F[A]]): F[List[A]] = F(lma.flatten)
F的例子是Option:
scala> val x: List[Option[Int]] = List( Some(1), None)
x: List[Option[Int]] = List(Some(1), None)
scala> Some(x.flatten)
res1: Some[List[Int]] = Some(List(1))
Run Code Online (Sandbox Code Playgroud)
我的回答(或其精神)在这里合法吗?
我得到以下编译时异常,但我确定它是否与我对类型构造函数缺乏理解有关.
Monad.scala:15:错误:未找到:值F
F(lma.flatten)