import { makeGeneric } from "../generics/generics.js"; import { Bool } from "../primitives/types.js"; import { makeTypeConstructor } from "../type_constructor.js"; import { getEq } from "../typeclasses/eq.js"; import { eqDictType } from "../typeclasses/eq_type.js"; import { fnType, setType } from "./types.js"; const symbolVersioned = Symbol("Versioned"); export const versionedType = makeTypeConstructor(symbolVersioned)(1); export const constructor = parents => alternatives => { return { parents, alternatives }; } const constructorType = makeGeneric(a => fnType (setType(versionedType(a))) (fnType (setType(a)) (versionedType(a)) ) ); const initial = x => ({ parents: new Set(), alternatives: new Set(x) }); const initialFnType = makeGeneric(a => fnType(a)(versionedType(a))); const eq = eqDict => vA => vB => { return getEq(eqDict)(vA.value,vB.value) // compare values && (vA.parents.symmetricDifference(vB.parents).size === 0); // compare parents } // EqDict a -> Versioned a -> Versioned a -> Bool const eqVersioned = makeGeneric(a => fnType (eqDictType(a)) (fnType (versionedType(a)) (fnType (versionedType(a)) (Bool) ) ) ); // EqDict a -> Versioned a -> Versioned a -> Versioned a -> Versioned a export const mergeThreeWay = eqDict => vLCA => vA => vB => { if (eq(eqDict)(vLCA)(vA)) { return vB; // vB successor of vA } if (eq(eqDict)(vLCA)(vB)) { return vA; // vA successor of vB } return mergeConcurrent(vLCA)(vA)(vB); }; export const mergePrimitives = vA => vB => vA.union(vB); // Versioned a -> Versioned a -> Versioned a export const mergePrimitivesType = makeGeneric(a => fnType (versionedType(a)) (fnType (versionedType(a)) (versionedType(a)) ) );