在Scala的foldLeft
中,我知道如何访问Scala中的accumulator
和element
值,但不知道Haskell。
我可以使用foldLeft
找出1到100之间的数字,当除以3时,有多少数字的余数为1:
scala> List.range(1, 101).foldLeft(0){ (acc, elem) =>
| if (elem % 3 == 1) acc + 1
| else acc
| }
res2: Int = 33
我如何在Haskell中做同样的事情?
答案 0 :(得分:5)
基本上是一对一的对应关系:
mySum :: [Int] -> Int
mySum xs = foldl (\acc elem ->
if elem `mod` 3 == 1
then acc + 1
else acc
) 0 xs
除了参数的语法和顺序之外,没有真正的区别。
对于未来的读者,建议在实践中避免使用foldl
。由于foldl
实施中的懒惰,大型列表可能发生空间泄漏。相反,有一个严格的版本foldl'
可以用作替代版本或右侧折叠foldr
,它具有位格式:
mySum xs = foldr (\elem acc -> -- order of arguments swapped
if elem `mod` 3 == 1
then acc + 1
else acc
) 0 xs
答案 1 :(得分:3)
这是您的Scala代码直接转换为Haskell:
foldl (\acc x -> if x `mod` 3 == 1 then acc + 1 else acc) 0 [1..100]
在Haskell中,由于它的懒惰using foldl
usually is not a good idea,更好的选择是foldl'
或foldr
,这里是foldr
版本:
foldr (\x acc -> if x `mod` 3 == 1 then acc + 1 else acc) 0 [1..100]
答案 2 :(得分:0)
它非常相似:
foldl (\acc x -> if (x `mod` 3 == 1) then acc + 1 else acc) 0 [1..100]
foldl的第一个参数是lambda,第二个是累加器0
,第三个是值的范围。
请参阅this question以了解foldl,foldl'之间的区别。和折叠。