public static IType InferType(Type type, IMetadataContainer container)
{
Type genericTypeDefinition = type.GetGenericArguments().Any() ? type.GetGenericTypeDefinition() : type;
if (typeof(IFunction<,>).IsAssignableFrom(genericTypeDefinition))
{
Type left = type.GetGenericArguments()[0];
Type right = type.GetGenericArguments()[1];
return new Types.ArrowType(InferType(left, container), InferType(right, container));
}
else if (typeof(Either<,>).IsAssignableFrom(genericTypeDefinition))
{
Type left = type.GetGenericArguments()[0];
Type right = type.GetGenericArguments()[1];
return new Types.SumType(InferType(left, container), InferType(right, container));
}
else if (typeof(Tuple<,>).IsAssignableFrom(genericTypeDefinition))
{
Type left = type.GetGenericArguments()[0];
Type right = type.GetGenericArguments()[1];
return new Types.ProductType(InferType(left, container), InferType(right, container));
}
else if (type.IsGenericParameter)
{
return new Types.TypeParameter(type.Name);
}
else
{
container.ResolveType(type.Name);
var genericParameters = type.GetGenericArguments().Select(t => InferType(t, container)).ToArray();
return new Types.TypeSynonym(type.Name, genericParameters);
}
}