import { makeCompareFn } from "../compare/dynamic.js"; import { compareTypes } from "../compare/type.js"; import { getInst, getType, newDynamic } from "../primitives/dynamic.js"; import { Dynamic, Type } from "../primitives/primitive_types.js"; import { getSymbol } from "../primitives/type.js"; import { emptyDict, get, get as getDict, set as setDict } from "../structures/dict.js"; import { fold as foldList } from "../structures/list.js"; import { add, emptySet, fold as foldSet } from "../structures/set.js"; import { symbolFunction } from "../structures/type_constructors.js"; const addEntry = env => i => t => { const setOfInstances = getInstances(env)(t); return setDict(env)(t)(add(setOfInstances)(i)); }; export const growEnv = env => dynamic => { const t = getType(dynamic); const typeDictWithEntry = addEntry(env )(getInst(dynamic))(t ); const typeDictWithType = addEntry(typeDictWithEntry)(t )(Type ); const typeDictWithDynamic = addEntry(typeDictWithType )(dynamic )(Dynamic); return typeDictWithDynamic }; export const module2Env = module => { return foldList(typeDict => dynamic => { try { return growEnv(typeDict)(dynamic); } catch (e) { console.log('warning:', e.message); return typeDict; } })(emptyDict(compareTypes))(module); }; export const getInstances = env => type => { return getDict(env)(type) || emptySet(makeCompareFn(type)); }; export const getTypes = env => { return getDict(env)(Type) || emptySet(compareTypes); }; export const getFunctions = env => { const types = getTypes(env); return foldSet(types => type => { if (getSymbol(type) === symbolFunction) { return [ ...types, ...foldSet (functions => fn => [ ...functions, newDynamic(fn)(type), ]) ([]) (getInstances(env)(type)), ]; } return types; })([])(types); };