'Makes a function to match two ranges. Accepts two types: either
\'set\', which defines a function which returns a set with all ranges
matching pall (pany is ignored), or \'bool\', which returns True if pall
matches for all ranges and pany matches for any one range. doc is the
dostring to give this function. pany may be none to ignore the any
match.
The predicates get a dict with two keys, \'r1\', \'r2\', which denote
whether the current range is present in range1 (self) and/or range2
(other) or none of the two, respectively.'

def _make_function(name, type, doc, pall, pany=None):

    if (type == 'set'):
        def f(self, other):
            coerced = self.__coerce__(other)
            if (coerced is NotImplemented):
                return NotImplemented
            other = coerced[1]
            newset = self.__class__.__new__(self.__class__)
            newset._min = min(self._min, other._min)
            newset._max = max(self._max, other._max)
            newset._ranges = []
            for (states, (start, stop)) in self._iterranges(self._ranges, other._ranges, newset._min, newset._max):
                if pall(states):
                    if (newset._ranges and (newset._ranges[(-1)][1] == start)):
                        newset._ranges[(-1)] = (newset._ranges[(-1)][0], stop)
                    else:
                        newset._ranges.append((start, stop))
            newset._ranges = tuple(newset._ranges)
            newset._hash = hash(self._ranges)
            return newset
    elif (type == 'bool'):
        def f(self, other):
            coerced = self.__coerce__(other)
            if (coerced is NotImplemented):
                return NotImplemented
            other = coerced[1]
            _min = min(self._min, other._min)
            _max = max(self._max, other._max)
            found = (not pany)
            for (states, (start, stop)) in self._iterranges(self._ranges, other._ranges, _min, _max):
                if (not pall(states)):
                    return False
                found = (found or pany(states))
            return found
    else:
        raise ValueError('Invalid    type    of    function    to    create.')
    try:
        f.func_name = name
    except TypeError:
        pass
    f.func_doc = doc
    return f
