package scotch.symbol.type;
import static java.util.stream.Collectors.joining;
import java.util.Set;
import java.util.function.Function;
import scotch.symbol.Symbol;
import scotch.util.Pair;
public abstract class TypeDescriptor {
public abstract <T> T accept(Visitor<T> visitor);
@Override
public abstract boolean equals(Object o);
public abstract Set<Symbol> getContext();
public abstract TypeDescriptor mapVariables(Function<TypeDescriptor, TypeDescriptor> function);
@Override
public abstract int hashCode();
@Override
public String toString() {
return gatherContext() + toString_();
}
protected String gatherContext() {
Set<Pair<VariableTypeDescriptor, Symbol>> context = gatherContext_();
if (context.isEmpty()) {
return "";
} else {
return "(" + context.stream()
.map(pair -> pair.into((type, symbol) -> symbol.getSimpleName() + " " + type.getName()))
.collect(joining(", ")) + ") => ";
}
}
protected abstract Set<Pair<VariableTypeDescriptor, Symbol>> gatherContext_();
protected abstract String toParenthesizedString();
protected abstract String toString_();
public interface Visitor<T> {
T visit(ConstructorTypeDescriptor type);
T visit(FunctionTypeDescriptor type);
T visit(InstanceTypeDescriptor type);
T visit(SumTypeDescriptor type);
T visit(VariableTypeDescriptor type);
}
}