import { compareNumbers } from "./primitives.js" import { get, length as lengthLs } from "../structures/list.js"; import { read, length as lengthSet } from "../structures/set.js"; import { constructorProduct, getLeft, getRight } from "../structures/product.js"; import { match } from "../structures/sum.js"; import { makeGeneric } from "../generics/generics.js"; import { lsType } from "../structures/types.js"; // (a -> a -> Int) -> [a] -> [a] -> Int export const compareLists = compareElems => x => y => { return compareNumbers(lengthLs(x))(lengthLs(y)) || (() => { for (let i=0; i a -> Int) -> (b -> b -> Int) -> (a, b) -> (a, b) -> Int export const compareProducts = compareLeft => compareRight => x => y => { return compareLeft (getLeft (x))(getLeft (y)) || compareRight(getRight(x))(getRight(y)); }; // (a -> a -> Int) -> (b -> b -> Int) -> (a | b) -> (a | b) -> Int export const compareSums = compareLeft => compareRight => x => y => { return match(x)(constructorProduct (leftValueX => match(y)(constructorProduct (leftValueY => compareLeft(leftValueX)(leftValueY)) ((rightValueY) => -1) // x is 'left' and y is 'right' => x < y )) (rightValueX => match(y)(constructorProduct (leftValueY => 1) // x is 'right' and y is 'left' => x > y (rightValueY => compareRight(rightValueX)(rightValueY)) )) ); }; // (a -> a -> Int) -> {a} -> {a} -> Int 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 => iterY => read(iterX) (keyX => nextX => read(iterY) // we could also use the comparison function that is embedded in the set object, // but to be consistent with the other comparison-functions, we don't. (keyY => nextY => compareElems(keyX)(keyY) || iterate(nextX)(nextY)) (0)) // end of set y (we'll never get here because sets are same size) (0) // end of set x; iterate(first(x))(first(y)); })(); };