To this date, the "zip" function in HList works like zip function or untyped List in scala. It will discard elements from the longer operand to be conformant to the shorter element:
val a = 1 :: 2 :: 3 :: HNil
val b = 4 :: 5 :: HNil
println(a.zip(b))
// this results in (1, 4) :: (2, 5) :: HNil
There is no operation for HList equivalent or similar to "zipAll" function, which takes 2 extra arguments denoting the placeholder for each operand if it is too short to be zipped with the other.
Is it possible to do it for shapeless.HList or scala 3 Tuple? What's the shorted way to implement this?
Thanks a lot for your opinion.
I follow what I see in the implementation of standard library.
The idea is that we have a clean interface that is typed and a runtime implementation of that interface that is efficient.
So, first of all, I need to encode the information of
ZipAll
inside a type:This particular type ensures that when we will use
ZipAll
, the corresponding resultant type will be correct. In particular,ZipAll
creates a tuple filled with the missing element using a standard type TL (if the left tuple is shorter than the right one) or TR (viceversa). Hence, all the next type tests are correct:Now, we can create the type signature of our implementation (using the extension method):
Now, we can create an unsafe implementation of
zipAll
:This should be hidden inside the implementation. Then, we can enforce the correct type of that unsafe implementation using
asInstanceOf...
:Then, I should use the new functionality seamlessly:
Probably it is not the best implementation so far (indeed the internal details are not type-safe), but it is kind of a pattern to implement safe interface with unsafe implementation (to achieve a good balance between type safety and performance).
Here the implementation of what I have describes so far in Scastie.