I am trying to figure it out how to chain functions in Scala.
I have the following code:
def multiPrint(list: List[Int], number: Int): Unit = {
list
.map(x => x * number)
.andThen(x => print(x))
}
but this does not print a result as I expected. It prints "()"
like if it was an empty list.
Then I tried like:
def multiPrint(list: List[Int], number: Int): Unit = {
list
.toStream
.map(x => x * number)
.print
}
This works, but toStream
is deprecated. Anyway, I would like to do it with andThen
. Any idea?
As the other answer mentioned, you are looking for foreach
...
But I thought, I'd explain what andThen
actually does here, which is kinda interesting.
So, if you look at a signature of andThen
:
trait PartialFunction[A, B] extends (A => B) {
...
def andThen[C](k: B => C): PartialFunction[A, C]
...
}
it should become clear that it doesn't do what you think it does.
It is actually a partial function combinator: given two partial functions, one f1: A => B, and and another f2: B => C, it creates and returns a third function, A => C, that first calls f1
with the given argument, and then invokes f2
with the result of execution of f1
.
So,
list
.map(_ * number)
.andThen(print(_))
Does not really print anything at all (I am guessing your saw ()
in the output when because you tried to print out the result of multiPrint
, which is a Unit
.
But, if you try something like this:
val foo = Seq(1,2,3).map(_ * 2).antThen(print(_))
foo(1)
You may get mildly surprised because this prints 4. foo(2)
will print 6. and foo(3)
? It throws an IndexOutOfBoundException
which may give you a hint on what's really going on.
Seq[Int]
in scala is actually a PartialFunction[Int, Int]
, that returns the Seq
element at the index given by the argument. Your .andThen
combined that function with print
, and created a new function foo
, that accesses the element of the result of .map
at the given index, andThen prints the result.
So, foo(1)
for instance, gets the element at index 1, which is 2*2
, and prints 4. And foo(3)
fails, because index 3 does not exist.
A note just for the sake of completness:
As the other answer mentions, to print out elements of seq one-by-one,
just use foreach
: Seq(1,2,3).map(_ *2).foreach(println)