import { map, pipe } from 'remeda' import { Mapper, MapperTwo } from './Mapper' import { Repr } from './Repr' export interface ReprValue { value: V repr: Repr } export const mkReprValueExplicit = (toString: Mapper) => (value: V, name: string): ReprValue => ({ value, repr: { name, value: toString(value) } }) type WithToString = { toString: (this: V) => string } export const mkReprValueImplicit = >(value: V, name: string): ReprValue => ({ value, repr: { name, value: value.toString() } }) export const mkReprValueNamedImplicit = string }>(value: V): ReprValue => ({ value, repr: { name: value.name, value: value.toString() } }) export const mkReprValueFunc = mkReprValueNamedImplicit export const rvi = mkReprValueImplicit export const rve = mkReprValueExplicit export const rvf = mkReprValueFunc // (value: Mapper): ReprValue> => ({ repr: { name: value.name, value: value.toString() }, value }) /** * TODO: doesn't support the types fully */ export const getReprValuesObject = , R extends Record>(record: R): Record => { return pipe( record, Object.entries, map(([key, value]) => [key, rvi(value, key)]), Object.fromEntries ) } export const mkReprValueOfMapper = (fun: ReprValue>, in1: ReprValue) => ({ value: fun.value(in1.value), repr: { name: `${fun.repr.name}(${in1.repr.name})`, value: `${fun.repr.name}(${in1.repr.value})`, }, }) /** * But it doesn't show the value of the function (which might or might not be relevant) */ export const mkReprValueOfMapperTwo = (fun: ReprValue>, in1: ReprValue, in2: ReprValue) => ({ value: fun.value(in1.value, in2.value), repr: { name: `${fun.repr.name}(${in1.repr.name}, ${in2.repr.name})`, value: `${fun.repr.name}(${in1.repr.value}, ${in2.repr.value})`, }, }) export const callMapper = mkReprValueOfMapper export const callMapperTwo = mkReprValueOfMapperTwo const example1 = ` * gt(a, b) * gt = (a: bigint, b: bigint) => a > b * a = 42 * b = 0 `