We can implement the zip method using unfold as follows:
def myZip(a: List[Int], b: List[Int]) ={
List.unfold(a, b){
case(a, b) if a.length > 0 & b.length >0 => Some( (a.head, b.head), (a.tail, b.tail))
case _ => None
}
}
It is easy to generalize this method to any finite number of lists to be zipped. But I cannot come up with an idea how to define a general zip function operating on unspecified in advance number of lists. Can you please give some hints?
The problem with generalisation is the output type, a zipN method would return a List[List[Any]] or a List[List[A]] the first one is not really useful, and the second one is usually called transpose instead.
BTW, you should prefer pattern matching there:
def myZip[A, B](as: List[A], bs: List[B]): List[(A, B)] =
List.unfold((as, bs)) {
case (a :: tailA, b :: tailB) =>
Some((a, b), (tailA, tailB))
case _ =>
None
}
It makes the code prettier (subjective) and arguably safer (objective)
Well, you can’t.
Frist things first, transponse is not a method on tuples, is a method on List(or any other collection).
Second, in that case, your result would be a List[List[Any]] which as I said, is not really useful at all.
You can see the implementation of such method here: Scastie - An interactive playground for Scala.
That is why I said that an arbitrary and useful zipN in current Scala is not simple to implement.
Alternatives could be, using source generators to generate enough overloads for most use cases; this is what cats does, or exploring a typeclass approach with implicit derivation for any tuple.