namespace meowlang.typechecker; public abstract record GenericTypeDescription : TypeDescription { protected readonly List GenericNames; public int Arity => GenericNames.Count; public GenericTypeDescription(List genericNames) { GenericNames = genericNames; } protected void CheckGenericNames(List genericTypes) { foreach (var typeId in genericTypes) { if (typeId.Key.IsGeneric) { if (GenericNames.IndexOf(typeId.Key.GenericParameterName!) < 0) { throw new UndeclaredGenericParameterException(typeId.Key.GenericParameterName!); } } CheckGenericNames(typeId.GenericParams); } } public abstract TypeDescription Concretize(List typeParams); protected TypeId ConcretizeGenericType(GenericTypeId genericType, List concreteTypes) { return new TypeId(ConcretizeGenericTypeRef(genericType.Key, concreteTypes), genericType.GenericParams.Select(x => ConcretizeGenericType(x, concreteTypes)).ToList()); } private Guid ConcretizeGenericTypeRef(PossiblyGenericTypeRef typeRef, List concreteTypes) { if (!typeRef.IsGeneric) return typeRef.TypeKey!.Value; var typeIndex = GenericNames.IndexOf(typeRef.GenericParameterName!); return concreteTypes[typeIndex]; } }