docs: def zip(self, enumerable, func):
          """
          Merges 2 Enumerables using the given function. If the 2 collections are of unequal length, then
          merging continues until the end of one of the collections is reached
          :param enumerable: Enumerable collection to merge with
          :param func: a function to perform the merging
          :return: Enumerable
          """
          if not isinstance(enumerable, Enumerable3):
              raise TypeError()
          return Enumerable3(itertools.zip_longest(self, enumerable)) \
              .where(lambda x: x[0] is not None and x[1] is not None) \
              .select(lambda x: func(x))