Accessing the Accumulator & Element in `foldl` - scala

In Scala's foldLeft, I know how to access the accumulator and element values in Scala, but not Haskell.
I could use foldLeft to find out, between 1 and 100, how many numbers have a remainder of 1 when divided by 3:
scala> List.range(1, 101).foldLeft(0){ (acc, elem) =>
| if (elem % 3 == 1) acc + 1
| else acc
| }
res2: Int = 33
How can I do the same in Haskell?

There's essentially a 1-to-1 correspondence:
mySum :: [Int] -> Int
mySum xs = foldl (\acc elem ->
if elem `mod` 3 == 1
then acc + 1
else acc
) 0 xs
Other than syntax and order of arguments, there's no real difference.
For future readers, it is recommended to avoid using foldl in practice. Due to laziness in foldl's implementation, space leaks can occur for large lists. Instead, there is a strict version foldl' which can be used as a drop-in replacement or the right fold foldr which has a bit format:
mySum xs = foldr (\elem acc -> -- order of arguments swapped
if elem `mod` 3 == 1
then acc + 1
else acc
) 0 xs

This is a direct translation of your Scala code to Haskell:
foldl (\acc x -> if x `mod` 3 == 1 then acc + 1 else acc) 0 [1..100]
In Haskell, because of laziness of it, using foldl usually is not a good idea, a better choose is foldl' or foldr, here is the foldr version:
foldr (\x acc -> if x `mod` 3 == 1 then acc + 1 else acc) 0 [1..100]

It's rather similar:
foldl (\acc x -> if (x `mod` 3 == 1) then acc + 1 else acc) 0 [1..100]
The first argument to foldl is the lambda, the second is the accumulator 0 and the third is the range of values.
Refer to this question to understand the differences between foldl, foldl' and foldr.

Related

foldLeft, foldRight difference on List Accumulator using Scala

This
Seq(2,5,-7,4).foldLeft(0)( (acc, a) =>
if (a > 0) acc + a else acc )
gives 11
This
Seq(2,5,-7,4).foldRight(0)( (acc, a) =>
if (a > 0) acc + a else acc )
gives 7
I am surprised why, as a straight aggregation has no such issue. I.e. the results are the same. For the above 11 seems correct to me.
Reason - some Scala implementation?
a and acc need to be reversed for foldRight. Checked with a few people, no one guessed or knew that. Hence the answer.
Seq(2,5,-7,4).foldRight(0)( (a, acc) =>
if (a > 0) acc + a else acc )
Thanks to #LMMS.

Scala function call without "." (dot) vs using "." (dot)

Can someone help me understand what is going on here. I have this definition for generating primes:
def primes: Stream[Long] = {
2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2).filter {
n => primes takeWhile (p => p*p <= n) forall (n % _ != 0)
}
}
def primes: Stream[Long] = {
2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2) filter {
n => primes takeWhile (p => p*p <= n) forall (n % _ != 0)
}
}
As you can see, both definitions are exactly similar except for the fact that the second one does not have a . before filter, whereas the first one does.
The problem is that running the first one, runs as expected and gives us primes, but the second one produces a java.lang.StackOverflowError.
Can someone shed some light on this? What is being passed to filter in either case?
Scala version: 2.11.6
Java version: 1.8.0_121
This is the full program I used to test each one:
object Main {
def primes: Stream[Long] = {
2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2) filter {
n => primes takeWhile (_ <= sqrt(n)) forall (n % _ != 0)
}
}
def primes2: Stream[Long] = {
2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2).filter {
n => primes2 takeWhile (p => p*p <= n) forall (n % _ != 0)
}
}
def main(args: Array[String]): Unit = {
println(primes.take(args.head.toInt).force)
}
}
The notation without . has the same precedence as that of any custom infix. So the first one applies filter only to Stream.iterate(11L)(_ + 2) - the second one applies it to 2 #:: 3 #:: 5 #:: 7 #::Stream.iterate(11L)(_ + 2).
The reason why the first one works is that the elements 2, 3, 5 and 7 are already in primes when the filter runs, so when the filter tries to use primes, those elements are already in it.
In the second code that's not the case because the filter is applied to those elements as well, meaning they wouldn't appear in primes until the filter returned true for them. But the filter needs to get elements from prime before it can return anything, so it loses itself in infinite recursion while trying to get at an element.
You need parenthesis:
def primes: Stream[Long] = {
2 #:: 3 #:: 5 #:: 7 #::(Stream.iterate(11L)(_ + 2) filter {
n => primes takeWhile (p => p*p <= n) forall (n % _ != 0)
})
}
As a rule of thumb, I usually use dots everywhere. It's easier to read and makes these sort of bugs harder to appear.

Haskell to Scala

Im new to Scala but I know something about functional programing thanks to Haskell and I'm looking for some examples, can you tell me how this would be in Scala?
scalarProduct :: [Int] -> [Int] -> Int
scalarProduct [] _ = 0
scalarProduct _ [] = 0
scalarProduct (x:xs) (y:ys) = if length(xs) == length (ys) then x*y + scalarProduct xs ys else 0
lessThan :: [Float] -> Float -> Int
lessThan [] _ = 0
lessThan (x:xs) n = if x < n then 1 + lessThan xs n else lessThan xs n
removeLast :: [a] -> [a]
removeLast [] = []
removeLast (x:xs) = if length(xs) == 0 then [] else [x] ++ removeLast xs
funcion :: Int -> Float
funcion x | x >= 6 = fromIntegral(product[9..x*2])
| x > 0 = fromIntegral(x) ** (1/4)
| x <= 0 = fromIntegral(product[1..(-x)]) * 5.0**fromIntegral(x)
If you want literal transformations, I think the below is as close as you will get. Bear in mind you have to put this inside an object/class/trait for this to compile (or just past it into the REPL).
def scalarProduct(list1: List[Int], list2: List[Int]): Int = (list1,list2) match {
case (Nil,_) => 0
case (_,Nil) => 0
case (x :: xs, y :: ys) => if (xs.length == ys.length) x*y + scalarProduct(xs,ys) else 0
}
def lessThan(floats: List[Float], bound: Float): Int = floats match {
case Nil => 0
case x :: xs => if (x < bound) 1 + lessThan(xs,n) else lessThan(xs,n)
}
def removeLast[A](list: List[A]): List[A] = list match {
case Nil => Nil
case x :: xs => if (xs.length == 0) Nil else List(x) ++ removeLast(xs)
}
def funcion(x: Int): Double = {
if (x >= 6)
(9 to x*2).product
else if (x > 0)
Math.pow(x,0.25)
else
(1 to -x).product.toDouble * Math.pow(5.0,x)
}
This code is pretty un-Scala-like. For example, the Scala way of doing the first three would probably be with an implicit conversion class RichList[A]. Also, these can all be done much more simply using library functions - but I don't think that's what you are looking for (else you would've used the corresponding library functions for the Haskell code).

How to understand function reduceLeft?

Why can (1 :: xs) be inserted?
One is cons'd onto beginning of list xs.
So List(3,2,1) becomes List(1,3,2,1) but what is significance of (1 :: xs)?
I'm having trouble understanding how this works :
def product(xs : List[Int]) = (1 :: xs) reduceLeft((x , y) => x * y)
In method signature a prefix operand (in this case (1 :: xs)) is not described? :
def reduceLeft[B >: A](f: (B, A) => B): B =
(1 :: xs) is not a prefix operand.
You are actually adding 1 before your list xs.
So product(List(3,2,1)) becomes List(1,3,2,1) reduceLeft((x,y) => x * y).
The reduceLeft function will take the 2 elements on the left and replace by the result of your function (x,y) => x * y.
In your case
List(1,3,2,1) => takes (1,3) and replaces by 1* 3 = 3 new List: List(3,2,1)
List(3,2,1) => takes (3,2) and replaces by 3 *2 = 6 new List: (6,1)
Finally takes (6,1) and get the final result 6.
As multiplying by one has no effect in the product, we add the number 1 before the List to avoid an error if the List is Empty.
Remove that and try product(List()) and you will see. If the List had at least on element (1::xs) will have no effect in your function
I believe you understand cons just fine. (1 :: xs) is simply another way to express List(1,3,2,1), on which you then invoke reduceLeft.
As for a better understanding of reduceLeft, I recently blogged this exact topic.
That's not a prefix operand--it's a method invocation on a List instance. The method reduceLeft is being called on the List (1 :: xs).
(1 :: xs) reduceLeft((x , y) => x * y)
can also be written as
(1 :: xs).reduceLeft((x , y) => x * y)
Or, even more explicitly:
val myList = (1 :: xs)
myList.reduceLeft((x , y) => x * y)

Converting a sequence of map operations to a for-comprehension

I read in Programming in Scala section 23.5 that map, flatMap and filter operations can always be converted into for-comprehensions and vice-versa.
We're given the following equivalence:
def map[A, B](xs: List[A], f: A => B): List[B] =
for (x <- xs) yield f(x)
I have a value calculated from a series of map operations:
val r = (1 to 100).map{ i => (1 to 100).map{i % _ == 0} }
.map{ _.foldLeft(false)(_^_) }
.map{ case true => "open"; case _ => "closed" }
I'm wondering what this would look like as a for-comprehension. How do I translate it?
(If it's helpful, in words this is:
take integers from 1 to 100
for each, create a list of 100 boolean values
fold each list with an XOR operator, back into a boolean
yield a list of 100 Strings "open" or "closed" depending on the boolean
I imagine there is a standard way to translate map operations and the details of the actual functions in them is not important. I could be wrong though.)
Is this the kind of translation you're looking for?
for (i <- 1 to 100;
val x = (1 to 100).map(i % _ == 0);
val y = x.foldLeft(false)(_^_);
val z = y match { case true => "open"; case _ => "closed" })
yield z
If desired, the map in the definition of x could also be translated to an "inner" for-comprehension.
In retrospect, a series of chained map calls is sort of trivial, in that you could equivalently call map once with composed functions:
s.map(f).map(g).map(h) == s.map(f andThen g andThen h)
I find for-comprehensions to be a bigger win when flatMap and filter are involved. Consider
for (i <- 1 to 3;
j <- 1 to 3 if (i + j) % 2 == 0;
k <- 1 to 3) yield i ^ j ^ k
versus
(1 to 3).flatMap { i =>
(1 to 3).filter(j => (i + j) % 2 == 0).flatMap { j =>
(1 to 3).map { k => i ^ j ^ k }
}
}