Esempio n. 1
0
def unify_single(t1, t2, solution, remaining):
    """
    Unify a single type equation and update the solution and remaining
    constraints.
    """
    if isinstance(t1, TypeVar) and isinstance(t2, TypeVar):
        remaining.append((t1, t2))
    elif isinstance(t1, TypeVar):
        if t1 in free(t2):
            raise error.UnificationError("Cannot unify recursive types")
        solution[t1].add(t2)
        remaining.append((t1, t2))
    elif isinstance(t2, TypeVar):
        if t2 in free(t1):
            raise error.UnificationError("Cannot unify recursive types")
        solution[t2].add(t1)
    elif isinstance(t1, TypeConstructor):
        verify(t1, t2)
    elif not isinstance(t1, Mono) and not isinstance(t2, Mono):
        verify(t1, t2)
    elif getattr(t1, "cls", None) == MEASURE and getattr(t2, "cls", None) == MEASURE:
        # If both types are measures, verify they can be promoted
        promote_units(t1, t2)
    else:
        verify(t1, t2)
        for arg1, arg2 in zip(t1.parameters, t2.parameters):
            unify_single(arg1, arg2, solution, remaining)
Esempio n. 2
0
def reify(solution, S=None):
    """
    Reify a typing solution, returning a new solution with types as concrete
    types as opposed to type sets.

    Parameters
    ----------
    solution : { TypeVar : set([ Type ]) }
        Typing solution

    Returns: { TypeVar : Type }
        Returns a solution reduced to concrete types only.
    """
    if S is None:
        S = IdentityDict()

    seen = set()
    queue = deque(dict_iteritems(solution))
    while queue:
        typevar, t = queue.popleft()
        t = frozenset(t)
        if typevar in S:
            continue

        typeset = solution[typevar]
        freevars = IdentityDict.fromkeys(chain(*[free(t) for t in typeset]))

        if not typeset:
            S[typevar] = typevar
            typeset.add(typevar)
            continue
        elif freevars and (typevar, t) not in seen:
            # Reify dependencies first
            queue.append((typevar, t))
            seen.add((typevar, t))
        elif freevars:
            typeset = set(substitute(S, t) for t in typeset)

        S[typevar] = promote_units(*typeset)

    return S