# Question Regarding Functional implementation of ZIP

While going thru the “Impossible For A Beginner To Read” book titled ‘Functional Programming In Scala’ by Paul Chiusano and Rúnar Bjarnason
Published by Manning Publications, 2014, I came across this interesting implementation of the “zipAll” function. This one I really find hard to completely understand due to the use of the ‘->’ symbol. Is there a Scala Guru in here that has the time to describe in English how this implementation is working. I can “sort of” understand most of it but I cannot find any explanation of the use of the ‘->’ in the implementation, though thru tracing the code it is sort of apparent. Just wondering if someone can describe its usage here to help enlighten us beginners a little as to its usage. I will post the code below but first need to explain a few things for those that have not attempted to read that book. The author creates an implementation of a Stream object that is used in the implementation of zipAll. So you can take that for granted; Also, Cons is used to construct Streams.

now here is the implementation of zipAll:

`````` def zipAll[B](s2: Stream[B]): Stream[(Option[A], Option[B])] =
zipWithAll(s2)((_, _))

def zipWithAll[B, C](s2: Stream[B])(f: (Option[A], Option[B]) => C): Stream[C] =
Stream.unfold((this, s2)) {
case (Empty, Empty)               => None
case (Cons(h, t), Empty)          => Some(f(Some(h()), Option.empty[B]) -> (t(), empty[B]))
case (Empty, Cons(h, t))          => Some(f(Option.empty[A], Some(h())) -> (empty[A] -> t()))
case (Cons(h1, t1), Cons(h2, t2)) => Some(f(Some(h1()), Some(h2())) -> (t1() -> t2()))
}
``````

My main question is regarding the use of the -> in the code above.

Honestly, this is another case of “you probably shouldn’t be reading this book yet, because you’re still learning the basics”.

`->` is a simple operator, built into the standard library, which builds `Tuple2`s; it is essentially synonymous with a comma. It is typically used in Maps and stuff like that – it’s the Scala-idiomatic way of making up key/value pairs. So:

``````  a -> b
``````

means precisely the same thing as:

``````  (a, b)
``````

but is usually used to signify a key/value relationship. It’s almost universally used in Map literals, such as:

``````  val myMap = Map(1 -> "a", 2 -> "b", 3 -> "c")
``````

It’s basically there to make such things more readable.

As to how they’re intending it in the book, I dunno, but that’s what the operator is. It’s just a common bit of syntax sugar in the libraries…

2 Likes

Not directly related to your question, but might be an useful resource:
https://scalabridge.gitbooks.io/curriculum/content/resources.html

This sorts the resources (books, blogs, and tools, etc) by learning levels. Enjoy learning Scala.

Oh I should have mentioned that. I am aware of how maps work in Scala using that symbol. But the usage here is something a little different than the map usage; This usage appears to magically generating a tuple that is the result of the case expression. Sort of interesting to say the least.

oh yes, I am aware of that: hehe

thanks for the information.

I think I understand what is going on in the zip function now. That use of -> threw me for a little loop but your explanation pointed me in the right direction. However , I am curious as to why the author didn’t just use a “tuple” like he had been doing in the previous examples in Chapter 5. I will investigate further now that I know it is relatively simple semantically speaking. The object is to create a tuple. But there probably is some real reason that the author used a -> instead of ( something, something).

Yes you are 100% correct. The following two sections of code produce identical results:

`````` def zipAll2[B](s2: Stream[B]): Stream[(Option[A], Option[B])] =
zipWithAll(s2)((_, _))

def zipAll[B](s2: Stream[B]): Stream[(Option[A], Option[B])] =
zipWithAll2(s2)((_, _))

def zipWithAll2[B, C](s2: Stream[B])(f: (Option[A], Option[B]) => C): Stream[C] =
Stream.unfold((this, s2)) {
case (Empty, Empty)               => None
case (Cons(h, t), Empty)          => Some(f(Some(h()), Option.empty[B]) -> (t(), empty[B]))
case (Empty, Cons(h, t))          => Some(f(Option.empty[A], Some(h())) -> (empty[A] -> t()))
case (Cons(h1, t1), Cons(h2, t2)) => Some(f(Some(h1()), Some(h2())) -> (t1() -> t2()))
}
def zipWithAll[B, C](s2: Stream[B])(f: (Option[A], Option[B]) => C): Stream[C] =
Stream.unfold((this, s2)) {
case (Empty, Empty)               => None
case (Cons(h, t), Empty)          => Some(f(Some(h()), Option.empty[B]) , (t(), empty[B]))
case (Empty, Cons(h, t))          => Some(f(Option.empty[A], Some(h())) , (empty[A] , t()))
case (Cons(h1, t1), Cons(h2, t2)) => Some(f(Some(h1()), Some(h2())) , (t1() , t2()))
}

driver code:
val list = cons(1, Stream(1, 2, 3, 4))
val list2 = cons(5, Stream(6, 7, 8))
println(list.zipAll2[Int](list2) toList)
println(list.zipAll[Int](list2) toList)

output:
List((Some(1),Some(5)), (Some(1),Some(6)), (Some(2),Some(7)), (Some(3),Some(8)), (Some(4),None))

List((Some(1),Some(5)), (Some(1),Some(6)), (Some(2),Some(7)), (Some(3),Some(8)), (Some(4),None))``````

I don’t know the authors’ intentions, but I’d guess `->` is used for
readability, since it reduces the number of parens needed. I usually choose

`Some(a -> b)`

`Some((a, b))`
Perhaps that is the reason. The author usually explains little things like that but this time he forgot to explain to the beginners that happen to be reading the book 