Example #1
0
        public void TestTypeclasses()
        {
            var initialState = new InferenceState(new FreshVariableStream(),
                                                  new TypeclassDeclaration("Eq",
                                                                           new TypeScheme(new TypeConstructor("int", new DataKind())),
                                                                           new TypeScheme(new QualifiedType(
                                                                                              new TypeApplication(new TypeConstructor("[]", new ArrowKind(new DataKind(), new DataKind())),
                                                                                                                  new TypeVariable("a", new DataKind())),
                                                                                              new Predicate("Eq", new TypeVariable("a", new DataKind()))), ("a", new DataKind()))),
                                                  new TypeclassDeclaration("Ord"),
                                                  new TypeclassDeclaration("Show"),
                                                  new TypeclassDeclaration("Read"),
                                                  new TypeclassDeclaration("Bounded"),
                                                  new TypeclassDeclaration("Enum"),
                                                  new TypeclassDeclaration("Functor"),
                                                  new TypeclassDeclaration("Monad"),
                                                  new TermVariableBinding("eq", new TypeScheme(new QualifiedType(
                                                                                                   PrimType.Fun(new TypeVariable("a", new DataKind()), new TypeVariable("a", new DataKind()), new TypeConstructor("bool", new DataKind())),
                                                                                                   new Predicate("Eq", new TypeVariable("a", new DataKind()))),
                                                                                               ("a", new DataKind()))),
                                                  new TermVariableBinding("zero", new TypeScheme(new QualifiedType(new TypeConstructor("int", new DataKind())))),
                                                  new TermVariableBinding("true", new TypeScheme(new QualifiedType(new TypeConstructor("bool", new DataKind())))),
                                                  new TermVariableBinding("show", new TypeScheme(new QualifiedType(
                                                                                                     PrimType.Fun(new TypeVariable("a", new DataKind()), new TypeConstructor("string", new DataKind())),
                                                                                                     new Predicate("Show", new TypeVariable("a", new DataKind()))),
                                                                                                 ("a", new DataKind()))),
                                                  new TermVariableBinding("read", new TypeScheme(new QualifiedType(
                                                                                                     PrimType.Fun(new TypeConstructor("string", new DataKind()), new TypeVariable("a", new DataKind())),
                                                                                                     new Predicate("Read", new TypeVariable("a", new DataKind()))),
                                                                                                 ("a", new DataKind()))));

            Assert.AreEqual(
                TypeInference.Infer(initialState, new TermVariable("eq")),
                new QualifiedType(PrimType.Fun(new TypeVariable("t0", new DataKind()), new TypeVariable("t0", new DataKind()), new TypeConstructor("bool", new DataKind())),
                                  new Predicate("Eq", new TypeVariable("t0", new DataKind()))));

            Assert.AreEqual(
                TypeInference.Infer(initialState, new Application(new TermVariable("eq"), new TermVariable("zero"))),
                new QualifiedType(PrimType.Fun(new TypeConstructor("int", new DataKind()), new TypeConstructor("bool", new DataKind()))));

            Assert.ThrowsException <Exception>(() =>
                                               TypeInference.Infer(initialState, new Application(new TermVariable("eq"), new TermVariable("true"))));

            Assert.ThrowsException <Exception>(() =>
                                               TypeInference.Infer(initialState, new LambdaAbstraction("x", new Application(new TermVariable("show"), new Application(new TermVariable("read"), new TermVariable("x"))))));
        }
        private T Open <T>(TypeScheme <T> scheme) where T : ITopLevelType <T>
        {
            var subst = scheme
                        .TypeVariables
                        .ToImmutableDictionary(x => x, x => (Type)FreshVar(x));

            return(scheme.Type.Apply(subst));
        }
        private TypeInference InferGeneralized(ITerm term, out TypeScheme generalized)
        {
            var state = this
                        .AddMark()
                        .Infer(term, out var ungeneralized)
                        .SkimContext(out var skimmed);

            generalized = this.MakeScheme(skimmed, ungeneralized);
            return(state);
        }
Example #4
0
        public ActionResult <TypeScheme> Get(string id)
        {
            string            schmea = System.IO.File.ReadAllText(ControllerConstants.ReferenceCodeSchemaFilePath);
            List <TypeScheme> items  = JsonConvert.DeserializeObject <List <TypeScheme> >(schmea);
            TypeScheme        item   = items.FirstOrDefault(sch => sch.Identifier.Equals(id, StringComparison.InvariantCultureIgnoreCase) || sch.Identifier.EndsWith(id, StringComparison.InvariantCultureIgnoreCase));

            if (item == null)
            {
                ErrorResponse notFoundError = new ErrorResponse(string.Format(CultureInfo.InvariantCulture, ErrorDetail.NotFound, id), ErrorDetail.Status404);
                return(this.NotFound(notFoundError));
            }
            return(item);
        }
        private TypeInference Specialize(TypeScheme scheme, out QualifiedType specialized)
        {
            var state = this;

            specialized = scheme.Body;
            foreach (var(name, kind) in scheme.Quantified)
            {
                state = state
                        .Fresh(out var tname)
                        .AddIntro(tname, kind);
                specialized = specialized.Substitute(name, new TypeVariable(tname, kind));
            }
            return(state);
        }
Example #6
0
        private TypeInference Specialize(TypeScheme scheme, out IType specialized)
        {
            var state = this;

            specialized = scheme.Body;
            foreach (var name in scheme.Quantified)
            {
                state = state
                        .Fresh(out var fresh)
                        .AddIntro(fresh);
                specialized = specialized.Substitute(name, new TypeVariable(fresh));
            }
            return(state);
        }
        private TypeInference InferGeneralized(ITerm term, out TypeScheme generalized, out IImmutableList <Predicate> deferred)
        {
            var state = this
                        .AddMark()
                        .Infer(term, out var ungeneralized)
                        .SkimContext(out var skimmed);
            var generalizedVariables = skimmed.Select(s => s.name);

            var(ds, rs) = ungeneralized.Context.SplitPredicates(state._state.Context, generalizedVariables);
            if (rs.FreeVariables().Except(generalizedVariables).Any())
            {
                throw new Exception($"Ambiguity detected in '{string.Join(",", rs.Select(p => p.ToString()))}'");
            }
            deferred    = ds;
            generalized = this.MakeScheme(skimmed, new QualifiedType(rs, ungeneralized.Head));
            return(state);
        }
 private TypeInference AddBinding(string name, TypeScheme type) =>
 new TypeInference(this._state.Push(new TermVariableBinding(name, type)));
Example #9
0
 public TermVariableBinding(string name, TypeScheme type)
 {
     this.Name = name; this.Type = type;
 }
        public void InferFloatTests()
        {
            var FloatTestInitialContext = new InferenceState(new FreshVariableStream(),
                                                             new TermVariableBinding("zero", new TypeScheme(new FloatType(new UnitPower(new TypeVariable("x"), 1)), ("x", Kind.Unit))),
                                                             new TermVariableBinding("one", new TypeScheme(new FloatType(new UnitIdentity()))),
                                                             new TermVariableBinding("mass", new TypeScheme(new FloatType(new UnitPower(new PrimitiveUnit("kg"), 1)))),
                                                             new TermVariableBinding("time", new TypeScheme(new FloatType(new UnitPower(new PrimitiveUnit("sec"), 1)))),
                                                             new TermVariableBinding("mul", new TypeScheme(new ArrowType(
                                                                                                               new FloatType(new UnitPower(new TypeVariable("a"), 1)),
                                                                                                               new FloatType(new UnitPower(new TypeVariable("b"), 1)),
                                                                                                               new FloatType(new UnitMultiply(new UnitPower(new TypeVariable("a"), 1), new UnitPower(new TypeVariable("b"), 1)))), ("a", Kind.Unit), ("b", Kind.Unit))),
                                                             new TermVariableBinding("plus", new TypeScheme(new ArrowType(
                                                                                                                new FloatType(new UnitPower(new TypeVariable("a"), 1)),
                                                                                                                new FloatType(new UnitPower(new TypeVariable("a"), 1)),
                                                                                                                new FloatType(new UnitPower(new TypeVariable("a"), 1))), ("a", Kind.Unit))),
                                                             new TermVariableBinding("div", new TypeScheme(new ArrowType(
                                                                                                               new FloatType(new UnitMultiply(new UnitPower(new TypeVariable("a"), 1), new UnitPower(new TypeVariable("b"), 1))),
                                                                                                               new FloatType(new UnitPower(new TypeVariable("a"), 1)),
                                                                                                               new FloatType(new UnitPower(new TypeVariable("b"), 1))),
                                                                                                           ("a", Kind.Unit), ("b", Kind.Unit))),
                                                             new TermVariableBinding("pair", new TypeScheme(new ArrowType(
                                                                                                                new FloatType(new UnitPower(new TypeVariable("a"), 1)),
                                                                                                                new FloatType(new UnitPower(new TypeVariable("b"), 1)),
                                                                                                                new FloatType(new UnitPower(new TypeVariable("a"), 1)),
                                                                                                                new FloatType(new UnitPower(new TypeVariable("b"), 1))),
                                                                                                            ("a", Kind.Unit), ("b", Kind.Unit)))
                                                             );

            Assert.AreEqual(
                TypeInference.Infer(FloatTestInitialContext, new TermVariable("zero")),
                new FloatType(new UnitPower(new TypeVariable("t0"), 1)));

            Assert.AreEqual(
                TypeInference.Infer(FloatTestInitialContext, new Application(new TermVariable("mul"), new TermVariable("mass"), new TermVariable("mass"))),
                new FloatType(new UnitPower(new PrimitiveUnit("kg"), 2)));

            Assert.AreEqual(
                TypeInference.Infer(FloatTestInitialContext,
                                    new LambdaAbstraction("a",
                                                          new LambdaAbstraction("b",
                                                                                new Application(new TermVariable("plus"), new TermVariable("a"), new TermVariable("b"))))),
                new ArrowType(new FloatType(new UnitPower(new TypeVariable("h0"), 1)),
                              new FloatType(new UnitPower(new TypeVariable("h0"), 1)),
                              new FloatType(new UnitPower(new TypeVariable("h0"), 1))));

            Assert.AreEqual(
                TypeInference.Infer(FloatTestInitialContext,
                                    new LambdaAbstraction("x",
                                                          new LetBinding("d", new Application(new TermVariable("div"), new TermVariable("x")),
                                                                         new Application(new TermVariable("pair"),
                                                                                         new Application(new TermVariable("d"), new TermVariable("mass")),
                                                                                         new Application(new TermVariable("d"), new TermVariable("time")))))),
                new ArrowType(new FloatType(new UnitPower(new TypeVariable("h0"), 1)),
                              new FloatType(new UnitMultiply(new UnitPower(new TypeVariable("h0"), 1), new UnitPower(new PrimitiveUnit("kg"), -1))),
                              new FloatType(new UnitMultiply(new UnitPower(new TypeVariable("h0"), 1), new UnitPower(new PrimitiveUnit("sec"), -1)))));

            Assert.AreEqual(
                TypeInference.Infer(FloatTestInitialContext,
                                    new LetBinding("recip", new Application(new TermVariable("div"), new TermVariable("one")),
                                                   new Application(new TermVariable("pair"),
                                                                   new Application(new TermVariable("recip"), new TermVariable("mass")),
                                                                   new Application(new TermVariable("recip"), new TermVariable("time"))))),
                new ArrowType(new FloatType(new UnitPower(new PrimitiveUnit("kg"), -1)), new FloatType(new UnitPower(new PrimitiveUnit("sec"), -1))));
        }
Example #11
0
        public Environment()
        {
            {
                var builder = ImmutableDictionary.CreateBuilder <string, LazyValue>();
                builder.Add("+", BuiltinFunction(BigInteger.Add));
                builder.Add("-", BuiltinFunction(BigInteger.Subtract));
                builder.Add("*", BuiltinFunction(BigInteger.Multiply));
                builder.Add("/", BuiltinFunction(BigInteger.Divide));
                builder.Add("%", BuiltinFunction(BigInteger.Remainder));
                builder.Add("negate", BuiltinFunction(BigInteger.Negate));
                builder.Add("powmod", BuiltinFunction(BigInteger.ModPow));

                builder.Add("==", BuiltinFunction((x, y) => x.CompareTo(y) == 0));
                builder.Add("!=", BuiltinFunction((x, y) => x.CompareTo(y) != 0));
                builder.Add(">", BuiltinFunction((x, y) => x.CompareTo(y) > 0));
                builder.Add(">=", BuiltinFunction((x, y) => x.CompareTo(y) >= 0));
                builder.Add("<", BuiltinFunction((x, y) => x.CompareTo(y) < 0));
                builder.Add("<=", BuiltinFunction((x, y) => x.CompareTo(y) <= 0));

                builder.Add("True", Defaults.True);
                builder.Add("False", Defaults.False);
                Values = builder.ToImmutableDictionary();
            }

            {
                var builder    = ImmutableDictionary.CreateBuilder <string, Type>();
                var unaryInt   = new FunctionType(new IntegralType(), new IntegralType());
                var binaryInt  = new FunctionType(new IntegralType(), unaryInt);
                var ternaryInt = new FunctionType(new IntegralType(), binaryInt);

                var gen       = new TypeVariable();
                var binaryGen = new TypeScheme(new HashSet <TypeVariable> {
                    gen
                },
                                               new FunctionType(gen, new FunctionType(gen, TypeDefaults.Bool)));

                builder.Add("+", binaryInt);
                builder.Add("-", binaryInt);
                builder.Add("*", binaryInt);
                builder.Add("/", binaryInt);
                builder.Add("%", binaryInt);
                builder.Add("negate", unaryInt);
                builder.Add("powmod", ternaryInt);

                builder.Add("==", binaryGen);
                builder.Add("!=", binaryGen);
                builder.Add(">", binaryGen);
                builder.Add(">=", binaryGen);
                builder.Add("<", binaryGen);
                builder.Add("<=", binaryGen);

                builder.Add("True", TypeDefaults.Bool);
                builder.Add("False", TypeDefaults.Bool);
                ValueTypes = builder.ToImmutableDictionary();
            }

            {
                var builder = ImmutableDictionary.CreateBuilder <string, DataConstructor>();
                builder.Add("True", Defaults.TrueConstructor);
                builder.Add("False", Defaults.FalseConstructor);
                Constructors = builder.ToImmutableDictionary();
            }

            {
                var builder = ImmutableDictionary.CreateBuilder <string, Type>();
                builder.Add("Int", new IntegralType());
                builder.Add("Float", new FloatingType());
                builder.Add("Bool", TypeDefaults.Bool);
                Types = builder.ToImmutableDictionary();
            }
        }