Scala foldLeft
在Java 8中的优势是什么?
我很想想它reduce
,但是减少必须返回与它减少的相同类型的东西.
例:
import java.util.List;
public class Foo {
// this method works pretty well
public int sum(List<Integer> numbers) {
return numbers.stream()
.reduce(0, (acc, n) -> (acc + n));
}
// this method makes the file not compile
public String concatenate(List<Character> chars) {
return chars.stream()
.reduce(new StringBuilder(""), (acc, c) -> acc.append(c)).toString();
}
}
Run Code Online (Sandbox Code Playgroud)
上面代码中的问题是acc
umulator:new StringBuilder("")
因此,任何人都可以指出我正确的foldLeft
/修复我的代码?
今天,当我使用一个小脚本时,我用foldl
而不是foldl'
.我得到了stack overflow
,所以我进口Data.List (foldl')
并对此感到满意.这是我的默认工作流程foldl
.只需foldl'
在懒惰版本评估时使用.
Real World Haskell
说我们应该使用foldl'
而不是foldl
在大多数情况下.Foldr Foldl Foldl'说
通常选择在
foldr
和之间foldl'
....
但是,如果组合函数在其第一个参数中是惰性的,则
foldl
可能会愉快地返回到达foldl'
异常的结果.
一个给定的例子:
(?) :: Int -> Int -> Int
_ ? 0 = 0
x ? y = x*y
list :: [Int]
list = [2, 3, undefined, 5, 0]
okey = foldl (?) 1 list
boom = foldl' (?) 1 list
Run Code Online (Sandbox Code Playgroud)
嗯,我很抱歉,但它相当学术,有趣但是学术上的例子.所以我在问,有没有实际使用的例子foldl …
我正在尝试学习函数式编程和Scala,所以我正在阅读Chiusano和Bjarnason的"Scala中的函数式编程".我无法理解左侧折叠和折叠右侧方法在列表的情况下做了什么.我在这里环顾四周,但我找不到一些初学友好的东西.所以本书提供的代码是:
def foldRight[A,B](as: List[A], z: B)(f: (A, B) => B): B = as match {
case Nil => z
case Cons(h, t) => f(h, foldRight(t, z)(f))
}
def foldLeft[A,B](l: List[A], z: B)(f: (B, A) => B): B = l match {
case Nil => z
case Cons(h,t) => foldLeft(t, f(z,h))(f)
}
Run Code Online (Sandbox Code Playgroud)
Cons和Nil是:
case class Cons[+A](head: A, tail: List[A]) extends List[A]
case object Nil extends List[Nothing]
Run Code Online (Sandbox Code Playgroud)
那么左右实际折叠的是什么呢?为什么需要"实用"方法?有许多其他方法使用它们,我也很难理解它们,因为我没有得到这两个.
如何在 Scala 中模拟以下行为?即在满足蓄能器的某些特定条件时继续折叠。
def foldLeftWhile[B](z: B, p: B => Boolean)(op: (B, A) => B): B
Run Code Online (Sandbox Code Playgroud)
例如
scala> val seq = Seq(1, 2, 3, 4)
seq: Seq[Int] = List(1, 2, 3, 4)
scala> seq.foldLeftWhile(0, _ < 3) { (acc, e) => acc + e }
res0: Int = 1
scala> seq.foldLeftWhile(0, _ < 7) { (acc, e) => acc + e }
res1: Int = 6
Run Code Online (Sandbox Code Playgroud)
更新:
根据@Dima 的回答,我意识到我的意图有点副作用。所以我让它与 同步takeWhile
,即如果谓词不匹配,则不会有任何进展。并添加更多示例以使其更清晰。(注意:这不适用于Iterator
s)
我有类型的问题,我不明白.在下面的代码中,我有两个方法half1
,half2
它们完全相同,只是half1
显式指定了返回类型.然而,当我在foldLeft中使用这两个方法时half
会导致编译器错误.这是代码.设置的行val c
有问题.
package org.bodhi.reactive.`try`
import scala.util.{Try, Success, Failure}
object Hello {
def main(args: Array[String]): Unit = {
val list = List(1,2,3)
Try(1024).flatMap(half1)
Try(1024).flatMap(half2)
half1(1024).flatMap(half1)
half2(1024).flatMap(half2)
val a = list.foldLeft(Try(1024))((accum, n) => accum.flatMap(half1))
val b = list.foldLeft(half1(1024))((accum, n) => accum.flatMap(half1))
val c = list.foldLeft(half2(1024))((accum, n) => accum.flatMap(half2)) // Compiler error
}
def half1(n: Int): Try[Int] =
if (n % 2 == 0) Success(n / 2)
else Failure(new Exception(s"WRONG $n"))
def half2(n: …
Run Code Online (Sandbox Code Playgroud) 我目前正在学习 Scala,我只是想知道左折叠。由于左折叠是柯里化的,因此您应该能够获得带有第一个参数的部分应用函数(PAF),如下所示。
(0 /: List(1, 2, 3)) _
Run Code Online (Sandbox Code Playgroud)
但实际上,我有一个错误。
<console>:8: error: missing arguments for method /: in trait TraversableOnce;
follow this method with `_' if you want to treat it as a partially applied function
Run Code Online (Sandbox Code Playgroud)
然后我通过向右折叠尝试了同样的事情,如下所示
(List(1, 2, 3) :\ 0) _
Run Code Online (Sandbox Code Playgroud)
这样,它就正确了,我可以得到一个PAF,例如((Int, Int) => Int) => Int
我知道我可以通过使用foldLeft方法获得PAF,但我想知道是否可以用“/:”来表达它。
我正在学习haskell,我试图编写自己的反向函数而不使用递归.
解决方案是这个功能:
myreverse = foldl (flip (:)) []
Run Code Online (Sandbox Code Playgroud)
我试图了解评估过程中发生的事情,比如说:
myreverse [1..5]
Run Code Online (Sandbox Code Playgroud)
我无法理解这里有什么翻盖.有人可以通过逐步解释来记下这里发生的事情吗?
我是Scala Collections的新手,目前我想将给定的字符串列表分成两个列表的元组(List[String], List[String])
,其中包含回文字符串列表和其余输入字符串列表.
例如,如果输入List("racecar", "abcd", "lilil", "effg")
应该是(List("racecar", "lilil"), List("abcd", "effg"))
我有一个使用过滤器的解决方案.但是,目前,尝试使用foldLeft优化我的解决方案.我的新方法如下:
def stringTuples2(strings: List[String]): (List[String], List[String]) = {
strings.foldLeft((List[String](), List[String]()))((b, a) => {
if (a.equals(a.reverse)) { b._1 :+ a; b }
else { b._2 :+ a; b }
})}
Run Code Online (Sandbox Code Playgroud)
I am not sure, what I am doing wrong, but the output for this solution is Tuple of two empty lists, i.e. (List(), List()).
Help is appreciated. Thanks!
这是一个Coursera课程,直到现在没有人可以帮助我.以下作品取自演讲.
object polynomials {
class Poly(terms0: Map[Int, Double]) {
def this(bindings: (Int, Double)*) = this(bindings.toMap)
val terms = terms0 withDefaultValue 0.0
def +(other: Poly) = new Poly((other.terms foldLeft terms)(addTerm))
def addTerm(terms: Map[Int, Double], term: (Int, Double)) : Map[Int, Double]= {
val (exp, coeff) = term
terms + (exp -> (coeff + terms(exp)))
}
override def toString =
(for ((exp, coeff) <- terms.toList.sorted.reverse)
yield coeff+"x^"+exp) mkString " + "
}
val p1 = new Poly(1 -> 2.0, 3 -> 4.0, 5 …
Run Code Online (Sandbox Code Playgroud) 我目前正在尝试解决以下练习:
给定一个Int
s列表,计算一个元素大于它后面的元素的次数。该练习迫使我不要使用显式递归。
以下是给出的一些示例输出function :: [Int] -> Int
:
function [1, 2, 3, 4, 5] == 0 -- only increasing numbers
function [5, 4, 3, 2, 1] == 4 -- only decreasing numbers
function [2, 1, 3, 1, 0, 4] == 3
-- 2 > 1
-- 3 > 1
-- 1 > 0
function [1] == 0 -- no successor
function [ ] == 0 -- no numbers at all
Run Code Online (Sandbox Code Playgroud)
我想以某种方式使用,foldl
但经过多次尝试和没有工作的想法我不得不放弃。
如何在不使用递归的情况下计算元素大于其后继元素的次数?