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); } }