# Path: expremigen/patterns/pattern.py
# class Pattern(metaclass=abc.ABCMeta):
#     """
#     abstract base class for a Pattern
#     """
# 
#     def __str__(self):
#         return "{0}".format(self.__class__.__name__)
# 
#     def __repr__(self):
#         return self.__str__()
# 
# Path: expremigen/patterns/pbinop.py
# class Pbinop(Pattern, metaclass=abc.ABCMeta):
#     """
#     abstract base class for patterns that rely on two patterns
#     """
# 
#     def __init__(self, a: Pattern, b: Pattern):
#         super().__init__()
#         self.a = a
#         self.b = b
# 
#     def __str__(self):
#         return "{0}({1}, {2})".format(self.__class__.__name__, self.a, self.b)
# 
# Path: expremigen/patterns/utils.py
# def flatten(l):
#     """
# 
#     :param l: list l
#     :return: iterator to flatten list l; Pchord are not flattened
#     """
#     for el in l:
#         if isinstance(el, Pattern) and not isinstance(el, Pchord):
#             yield from flatten(el)
#         else:
#             yield el


import itertools
import operator
from expremigen.patterns.pattern import Pattern
from expremigen.patterns.pbinop import Pbinop
from expremigen.patterns.utils import flatten



class Padd(Pbinop):
    """
    pattern that returns the sum of two other patterns
    """

    def __init__(self, a: Pattern, b: Pattern):
        super().__init__(a, b)

    def __iter__(self):

# Path: expremigen/patterns/pattern.py
# class Pattern(metaclass=abc.ABCMeta):
#     """
#     abstract base class for a Pattern
#     """
# 
#     def __str__(self):
#         return "{0}".format(self.__class__.__name__)
# 
#     def __repr__(self):
#         return self.__str__()
# 
# Path: expremigen/patterns/pbinop.py
# class Pbinop(Pattern, metaclass=abc.ABCMeta):
#     """
#     abstract base class for patterns that rely on two patterns
#     """
# 
#     def __init__(self, a: Pattern, b: Pattern):
#         super().__init__()
#         self.a = a
#         self.b = b
# 
#     def __str__(self):
#         return "{0}({1}, {2})".format(self.__class__.__name__, self.a, self.b)
# 
# Path: expremigen/patterns/utils.py
# def flatten(l):
#     """
# 
#     :param l: list l
#     :return: iterator to flatten list l; Pchord are not flattened
#     """
#     for el in l:
#         if isinstance(el, Pattern) and not isinstance(el, Pchord):
#             yield from flatten(el)
#         else:
#             yield el


# Path: expremigen/patterns/padd.py
import itertools
import operator
from expremigen.patterns.pattern import Pattern
from expremigen.patterns.pbinop import Pbinop
from expremigen.patterns.utils import flatten




class Padd(Pbinop):
    """
    pattern that returns the sum of two other patterns
    """

    def __init__(self, a: Pattern, b: Pattern):
        super().__init__(a, b)

    def __iter__(self):

        return flatten(i for i in itertools.starmap(operator.__add__, zip(self.a, self.b)))