create 'Ordering' type
This commit is contained in:
parent
77dfc8b182
commit
b0023afe8c
15 changed files with 158 additions and 117 deletions
|
|
@ -1,9 +1,9 @@
|
|||
import { getInst, getType } from "../primitives/dynamic.js";
|
||||
import { SymbolBool, SymbolBottom, SymbolByte, SymbolChar, SymbolDouble, SymbolDynamic, SymbolInt, SymbolUUID, SymbolType, SymbolUnit } from "../primitives/primitive_types.js";
|
||||
import { SymbolBool, SymbolBottom, SymbolByte, SymbolChar, SymbolDouble, SymbolDynamic, SymbolInt, SymbolUUID, SymbolType, SymbolUnit, SymbolOrdering } from "../primitives/primitive_types.js";
|
||||
import { UNBOUND_SYMBOLS } from "../primitives/typevars.js";
|
||||
import { symbolDict, symbolFunction, symbolList, symbolProduct, symbolSet, symbolSum } from "../structures/type_constructors.js";
|
||||
import { prettyT } from "../util/pretty.js";
|
||||
import { compareBools, compareNumbers, compareStrings, compareSymbols, compareUnits } from "./primitives.js";
|
||||
import { compareBools, compareDoubles, compareOrderings, compareStrings, compareSymbols, compareUnits } from "./primitives.js";
|
||||
import { compareDicts, compareFunctions, compareLists, compareProducts, compareSets, compareSums } from "./structures.js";
|
||||
import { compareTypes } from "./type.js";
|
||||
|
||||
|
|
@ -14,25 +14,26 @@ export const compareDynamic = x => y =>
|
|||
const cannotCompareTypeVarInstances = _ => _ => { throw new Error("Cannot compare instance of type variables"); }
|
||||
|
||||
const typeSymbolToCmp = new Map([
|
||||
[SymbolInt , compareNumbers],
|
||||
[SymbolBool , compareBools],
|
||||
[SymbolDouble , compareNumbers],
|
||||
[SymbolByte , compareNumbers],
|
||||
[SymbolChar , compareStrings],
|
||||
[SymbolUnit , compareUnits],
|
||||
[SymbolBottom , _ => _ => { throw new Error("Bottom!"); }],
|
||||
[SymbolUUID , compareSymbols],
|
||||
[SymbolInt , compareDoubles ],
|
||||
[SymbolBool , compareBools ],
|
||||
[SymbolDouble , compareDoubles ],
|
||||
[SymbolByte , compareDoubles ],
|
||||
[SymbolChar , compareStrings ],
|
||||
[SymbolUnit , compareUnits ],
|
||||
[SymbolBottom , _ => _ => { throw new Error("Bottom!"); }],
|
||||
[SymbolUUID , compareSymbols ],
|
||||
// [SymbolGenericType, ?] TODO
|
||||
[SymbolType , compareTypes],
|
||||
[SymbolDynamic, compareDynamic],
|
||||
[SymbolType , compareTypes ],
|
||||
[SymbolDynamic , compareDynamic ],
|
||||
[SymbolOrdering, compareOrderings],
|
||||
|
||||
// these functions take extra comparison callbacks:
|
||||
[symbolFunction, compareFunctions],
|
||||
[symbolSum , compareSums],
|
||||
[symbolProduct , compareProducts],
|
||||
[symbolList , compareLists],
|
||||
[symbolSet , compareSets],
|
||||
[symbolDict , compareDicts],
|
||||
[symbolSum , compareSums ],
|
||||
[symbolProduct , compareProducts ],
|
||||
[symbolList , compareLists ],
|
||||
[symbolSet , compareSets ],
|
||||
[symbolDict , compareDicts ],
|
||||
|
||||
// even though we cannot compare typevar instances,
|
||||
// we still need to give a function or shit will break
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { getDefaultTypeParser } from "../parser/type_parser.js";
|
||||
import { newDynamic } from "../primitives/dynamic.js";
|
||||
import { compareDynamic, makeCompareFn } from "./dynamic.js";
|
||||
|
||||
const mkType = getDefaultTypeParser();
|
||||
|
||||
export const ModuleCompareDynamic = [
|
||||
newDynamic(makeCompareFn )(mkType("Type -> a -> a -> Int")),
|
||||
newDynamic(compareDynamic)(mkType("Dynamic -> Dynamic -> Int")),
|
||||
newDynamic(makeCompareFn )(mkType("Type -> a -> a -> Ordering")),
|
||||
newDynamic(compareDynamic)(mkType("Dynamic -> Dynamic -> Ordering")),
|
||||
];
|
||||
|
|
@ -1,18 +1,25 @@
|
|||
// Total ordering of primitive types
|
||||
|
||||
export const compareNumbers = x => y => {
|
||||
export const compareInts = x => y => {
|
||||
if (typeof(x) !== 'bigint' || typeof(y) !== 'bigint') {
|
||||
throw new Error(`was only meant to compare bigints! got ${x} and ${y}`);
|
||||
}
|
||||
return (x < y) ? -1 : (x > y) ? 1 : 0;
|
||||
};
|
||||
|
||||
export const compareDoubles = x => y => {
|
||||
if (typeof(x) !== 'number' || typeof(y) !== 'number') {
|
||||
throw new Error(`was only meant to compare numbers! got ${x} and ${y}`);
|
||||
}
|
||||
return (x < y) ? -1 : (x > y) ? 1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
export const compareStrings = x => y => {
|
||||
if (typeof(x) !== 'string' || typeof(y) !== 'string') {
|
||||
throw new Error(`was only meant to compare strings! got ${x} and ${y}`);
|
||||
}
|
||||
return (x < y) ? -1 : (x > y) ? 1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
export const compareBools = x => y => {
|
||||
if (typeof(x) !== 'boolean' || typeof(y) !== 'boolean') {
|
||||
|
|
@ -26,3 +33,5 @@ export const compareUnits = _ => _ => 0;
|
|||
|
||||
// Symbols are encoded as strings
|
||||
export const compareSymbols = a => b => compareStrings(a)(b);
|
||||
|
||||
export const compareOrderings = a => b => compareDoubles(a)(b);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { getDefaultTypeParser } from "../parser/type_parser.js";
|
||||
import { newDynamic } from "../primitives/dynamic.js";
|
||||
import { compareBools, compareNumbers, compareSymbols, compareUnits } from "./primitives.js";
|
||||
import { compareBools, compareDoubles, compareInts, compareOrderings, compareSymbols, compareUnits } from "./primitives.js";
|
||||
|
||||
const mkType = getDefaultTypeParser();
|
||||
|
||||
export const ModuleComparePrimitives = [
|
||||
newDynamic(compareNumbers)(mkType("Double -> Double -> Int")),
|
||||
newDynamic(compareBools )(mkType("Bool -> Bool -> Int")),
|
||||
newDynamic(compareUnits )(mkType("Unit -> Unit -> Int")),
|
||||
newDynamic(compareSymbols)(mkType("UUID -> UUID -> Int")),
|
||||
newDynamic(compareInts )(mkType("Int -> Int -> Ordering" )),
|
||||
newDynamic(compareDoubles )(mkType("Double -> Double -> Ordering" )),
|
||||
newDynamic(compareBools )(mkType("Bool -> Bool -> Ordering" )),
|
||||
newDynamic(compareUnits )(mkType("Unit -> Unit -> Ordering" )),
|
||||
newDynamic(compareSymbols )(mkType("UUID -> UUID -> Ordering" )),
|
||||
newDynamic(compareOrderings)(mkType("Ordering -> Ordering -> Ordering")),
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Total ordering of composed types
|
||||
|
||||
import { compareNumbers, compareStrings } from "./primitives.js"
|
||||
import { compareDoubles, compareStrings } from "./primitives.js"
|
||||
import { get, length as lengthLs } from "../structures/list.js";
|
||||
import { read as readSet, length as lengthSet, first as firstSet } from "../structures/set.js";
|
||||
import { read as readDict, length as lengthDict, first as firstDict } from "../structures/dict.js";
|
||||
|
|
@ -13,7 +13,7 @@ export const compareFunctions = _compareInput => _compareOutput => x => y => {
|
|||
}
|
||||
|
||||
export const compareLists = compareElems => x => y => {
|
||||
return compareNumbers(lengthLs(x))(lengthLs(y))
|
||||
return compareDoubles(lengthLs(x))(lengthLs(y))
|
||||
|| (() => {
|
||||
for (let i=0; i<lengthLs(x); i++) {
|
||||
const elemCmp = compareElems(get(x)(i))(get(y)(i));
|
||||
|
|
@ -50,7 +50,7 @@ export const compareSums = compareLeft => compareRight => x => y => {
|
|||
};
|
||||
|
||||
export const compareSets = compareElems => x => y => {
|
||||
return compareNumbers(lengthSet(x))(lengthSet(y))
|
||||
return compareDoubles(lengthSet(x))(lengthSet(y))
|
||||
|| (() => {
|
||||
// sets have same size -> iterate over both sets and compare their elements pairwise
|
||||
// because of the underlying red-black tree, iteration happens in ordered fashion
|
||||
|
|
@ -71,7 +71,7 @@ export const compareSets = compareElems => x => y => {
|
|||
};
|
||||
|
||||
export const compareDicts = compareKeys => compareValues => x => y => {
|
||||
return compareNumbers(lengthDict(x))(lengthDict(y))
|
||||
return compareDoubles(lengthDict(x))(lengthDict(y))
|
||||
|| (() => {
|
||||
// dicts have same size -> iterate over both and compare their entries pairwise
|
||||
// because of the underlying red-black tree, iteration happens in ordered fashion
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ import { compareDicts, compareLists, compareProducts, compareSets, compareSums }
|
|||
const mkType = getDefaultTypeParser();
|
||||
|
||||
export const ModuleCompareStructures = [
|
||||
newDynamic(compareLists)(mkType("(a -> a -> Int) -> [a] -> [a] -> Int")),
|
||||
newDynamic(compareLists)(mkType("(a -> a -> Ordering) -> [a] -> [a] -> Ordering")),
|
||||
|
||||
newDynamic(compareProducts)(mkType("(a -> a -> Int) -> (b -> b -> Int) -> (a*b) -> (a*b) -> Int")),
|
||||
newDynamic(compareProducts)(mkType("(a -> a -> Ordering) -> (b -> b -> Ordering) -> (a*b) -> (a*b) -> Ordering")),
|
||||
|
||||
newDynamic(compareSums)(mkType("(a -> a -> Int) -> (b -> b -> Int) -> (a+b) -> (a+b) -> Int")),
|
||||
newDynamic(compareSums)(mkType("(a -> a -> Ordering) -> (b -> b -> Ordering) -> (a+b) -> (a+b) -> Ordering")),
|
||||
|
||||
newDynamic(compareSets)(mkType("(a -> a -> Int) -> {a} -> {a} -> Int")),
|
||||
newDynamic(compareSets)(mkType("(a -> a -> Ordering) -> {a} -> {a} -> Ordering")),
|
||||
|
||||
newDynamic(compareDicts)(mkType("(a -> a -> Int) -> (b -> b-> Int) -> (a => b) -> (a => b) -> Int"))
|
||||
newDynamic(compareDicts)(mkType("(a -> a -> Ordering) -> (b -> b-> Ordering) -> (a => b) -> (a => b) -> Ordering"))
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { getParams, getSymbol } from "../primitives/type.js";
|
||||
import { compareBools, compareNumbers, compareSymbols } from "./primitives.js";
|
||||
import { compareBools, compareDoubles, compareSymbols } from "./primitives.js";
|
||||
import { compareLists } from "./structures.js";
|
||||
|
||||
const __compareTypes = state => typeX => typeY => {
|
||||
|
|
@ -20,7 +20,7 @@ const __compareTypes = state => typeX => typeY => {
|
|||
// both sub-types have been visited already in an enclosing call
|
||||
// if they were being compared in the same enclosing call, we assume they are equal!
|
||||
// (we cannot compare them, that would result in endless recursion)
|
||||
return compareNumbers(state.comparing.get(pX))(pY);
|
||||
return compareDoubles(state.comparing.get(pX))(pY);
|
||||
}
|
||||
// none have been visited -> recursively compare
|
||||
return __compareTypes(state)(pX)(pY);
|
||||
|
|
|
|||
|
|
@ -5,5 +5,5 @@ import { compareTypes } from "./type.js";
|
|||
const mkType = getDefaultTypeParser();
|
||||
|
||||
export const ModuleCompareTypes = [
|
||||
newDynamic(compareTypes)(mkType("Type -> Type -> Int")),
|
||||
newDynamic(compareTypes)(mkType("Type -> Type -> Ordering")),
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue