dope2/tests/generics.js

81 lines
No EOL
1.6 KiB
JavaScript

import assert from "node:assert";
import { assignFn, assignFnSubstitutions, makeGeneric, unify, UnifyError } from "../lib/generics/generics.js";
import { getDefaultTypeParser } from "../lib/parser/type_parser.js";
import { prettyT } from "../lib/util/pretty.js";
import { TYPE_VARS, UNBOUND_SYMBOLS } from "../lib/primitives/typevars.js";
const mkType = getDefaultTypeParser();
// It would be better to compare the types directly with 'compareTypes', but the assert-module does not allow passing a custom comparison function.
assert.equal(
// actual
prettyT(
unify(
mkType("(a -> Int)"),
makeGeneric(() => mkType("[Bool] -> Int")),
)
),
// expected
"([Bool] -> Int)",
);
assert.equal(
// actual
prettyT(
unify(
mkType("(a -> a) -> b"),
mkType("(Bool -> Bool) -> a"),
)
),
// expected
"((Bool -> Bool) -> a)",
);
assert.equal(
// actual
prettyT(
assignFn(
mkType("(a -> b) -> [a] -> [b]"),
mkType("a -> a")
)
),
// expected
"([a] -> [a])",
);
assert.equal(
// actual
prettyT(
assignFn(
mkType("(a -> Int) -> [a] -> a"),
mkType("a -> a")
)
),
// expected
"([Int] -> Int)",
);
assert.throws(
() => {
unify(
mkType("Int"),
mkType("Bool")
)
},
// expected error
UnifyError,
);
const [inType, inSubst, outType, outSubst] = assignFnSubstitutions(
mkType("Int -> Int"),
mkType("b"),
);
assert.equal(prettyT(inType), "Int");
assert.equal(prettyT(outType), "Int");
assert.equal(inSubst.size, 1);
assert.equal(prettyT(
inSubst.get(UNBOUND_SYMBOLS[1]) // b
), "Int")
assert.equal(outSubst.size, 0);