add a new action with specific priority

        >>> delegate: Delegate
        >>> delegate.insert(lambda task, product, ctx: print(product), where=Delegate.Where.after(lambda action: action.__name__ == 'myfunc'))
        the codes above inserts an action after the specific action whose name is 'myfunc'.

def insert(self, action: Action, where: 'Union[int, Delegate.Where]'):
        """
        add a new action with specific priority

        >>> delegate: Delegate
        >>> delegate.insert(lambda task, product, ctx: print(product), where=Delegate.Where.after(lambda action: action.__name__ == 'myfunc'))
        the codes above inserts an action after the specific action whose name is 'myfunc'.
        """
        if isinstance(where, int):
            self.actions.insert(where, action)
            return

        here = where(self.actions)
        self.actions.insert(here, action)