// Total ordering of composed types import { compareNumbers, 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"; import { getLeft, getRight } from "../structures/product.js"; import { match } from "../structures/sum.js"; export const compareFunctions = _compareInput => _compareOutput => x => y => { // dirty but does the job return compareStrings(x.toString())(y.toString()); } export const compareLists = compareElems => x => y => { return compareNumbers(lengthLs(x))(lengthLs(y)) || (() => { for (let i=0; i compareRight => x => y => { return compareLeft (getLeft (x))(getLeft (y)) || compareRight(getRight(x))(getRight(y)); }; export const compareSums = compareLeft => compareRight => x => y => { // console.log("compareSums...", x, y) return match(x) (leftValueX => match(y) (leftValueY => compareLeft(leftValueX)(leftValueY)) // both are left ((_rightValueY) => { // console.log("x is 'left' and y is 'right' => x < y") return -1; }) // x is 'left' and y is 'right' => x < y ) (rightValueX => match(y) (_leftValueY => { // console.log("x is 'right' and y is 'left' => x > y"); return 1; }) // x is 'right' and y is 'left' => x > y (rightValueY => compareRight(rightValueX)(rightValueY)) // both are right ); }; export const compareSets = compareElems => x => y => { return compareNumbers(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 const iterate = iterX => entryY => match(readSet(iterX)) (entryX => match(readSet(entryY)) (resultY => compareElems (getLeft(entryX)) (getLeft(resultY)) || iterate (getRight(entryX)) (getRight(resultY))) (_ => 0)) (_ => 0); // we made it, sets are equal return iterate(firstSet(x))(firstSet(y)); })(); }; export const compareDicts = compareKeys => compareValues => x => y => { return compareNumbers(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 const iterate = iterX => iterY => match(readDict(iterX)) (entryX => match(readDict(iterY)) (entryY => compareKeys (getLeft(getLeft(entryX))) (getLeft(getLeft(entryY))) || compareValues (getRight(getLeft(entryX))) (getRight(getLeft(entryY))) || iterate (getRight(entryX)) (getRight(entryY))) (_ => 0)) (_ => 0); // we made it, dicts are equal return iterate(firstDict(x))(firstDict(y)); })(); };