public override IType Infer(ITypeSystem system, IEnvironment env, IList <IType> types) { if (Type == null) { var annotation = AsAnnotationType(system, env, types); if (annotation != null) { return(annotation); } } var args = Args.Select(arg => system.Infer(env, ToFormal(system, env, types, arg), types)).ToList(); var expr = (Node)Spec; var self = system.Infer(env, expr, types); IType @out; if (Type != null) { var ctor = !(Type is IType) ? system.Const(env, (string)Type) : (IType)Type; @out = system.Infer(env, Apply(Var(ctor.Id, ctor), args.Select(arg => Const(arg)).ToArray(), IsAnnotation), types); } else { @out = system.NewGeneric(); args.Add(@out); system.Unify(system.NewType(TypeSystem.Function, args.ToArray()), self); } return(@out); }
public override IType Infer(ITypeSystem system, IEnvironment env, IList <IType> types) { var scope = env.Local(system); var known = new List <IType>(types); var args = new List <IType>(); foreach (var arg in Args) { IType type; Var var; if (!(arg is Define)) { var = (Var)arg; if (var.Type != null) { type = !(var.Type is IType) ? system.Const(scope, (string)var.Type) : (IType)var.Type; } else { type = system.NewGeneric(); known.Add(type); } scope[var.Id] = type; } else { var spec = ((Define)arg).Body; var = (Var)((Define)arg).Spec; type = system.NewGeneric(); system.Unify(type, system.Infer(scope, spec, known)); scope[var.Id] = type; known.Add(type); } args.Add(type); if (!type.Value.IsConstructor) { type.Value.Bind(var.Id); } } args.Add(system.Infer(scope, Body is Let ? Body.Args[Body.Args.Length - 1] : Body, known)); if (Type != null) { system.Unify(args[args.Count - 1], !(Type is IType) ? system.Const(scope, (string)Type) : (IType)Type); } return(system.NewType(TypeSystem.Function, args.ToArray())); }
public override IType Infer(ITypeSystem system, IEnvironment env, IList <IType> types) => !(Spec is IType) ? system.Const(env, (string)Spec) : (IType)Spec;