uti | id | title | platforms | |
---|---|---|---|---|
com.xamarin.workbook |
3a1d5215-9db7-48dd-8f1d-4bab8dcd4f83 |
Curry |
|
Type CurryGeneric(Type genericType, params Type[] bound)
{
if (!genericType.IsGenericTypeDefinition) {
var genericDefinition = genericType.GetGenericTypeDefinition();
var unboundArgumentsArray = genericType.GetGenericArguments().Select((t, i) => t == genericDefinition.GetGenericArguments()[i]).ToArray();
var splattedArguments = new List<Type>();
var bindingStack = new Stack<Type>(bound);
for (var i = 0; i < unboundArgumentsArray.Length; i++) {
if (unboundArgumentsArray[i]) {
// This is an unbound argument?
splattedArguments.Add(bindingStack.Pop());
} else {
splattedArguments.Add(genericType.GetGenericArguments()[i]);
}
}
return CurryGeneric(genericDefinition, splattedArguments.ToArray());
}
if (genericType.GetGenericArguments().Length < bound.Length)
throw new ArgumentException();
var typeArguments = new List<Type>(bound);
if (genericType.GetGenericArguments().Length > bound.Length) {
for (var i = bound.Length; i < genericType.GetGenericArguments().Length; i++) {
typeArguments.Add(genericType.GetGenericArguments()[i]);
}
}
return genericType.MakeGenericType(typeArguments.ToArray());
}
CurryGeneric(typeof(C<,>), typeof(int));
CurryGeneric(typeof(C<,>));
CurryGeneric(CurryGeneric(typeof(C<,>), typeof(int)), typeof(string));
The funky stack/list interleaving in the upward recursive case (i.e. the first branch) is probably unnecessary but it's 3 AM I'll fix it later.