ValueClass

This commit is contained in:
Tony Garnock-Jones 2023-05-12 11:25:56 +02:00
parent 7e088ef8b3
commit a167e97c00
1 changed files with 55 additions and 0 deletions

View File

@ -6,6 +6,22 @@ import { annotate, Annotated } from "./annotated";
import { Double, Float, Single } from "./float";
import { Embedded } from "./embedded";
export enum ValueClass {
Boolean,
Float,
Double,
SignedInteger,
String,
ByteString,
Symbol,
Record,
Sequence,
Set,
Dictionary,
Embedded,
Annotated, // quasi-class
}
export type Fold<T, R = Value<T>> = (v: Value<T>) => R;
export interface FoldMethods<T, R> {
@ -86,6 +102,45 @@ export class MapFold<T, R> extends ValueFold<T, R> {
}
}
export function valueClass<T>(v: Value<T>): ValueClass {
switch (typeof v) {
case 'boolean':
return ValueClass.Boolean;
case 'number':
if (!Number.isInteger(v)) {
throw new Error("Non-integer number in Preserves valueClass; missing SingleFloat/DoubleFloat wrapper?");
} else {
return ValueClass.SignedInteger;
}
case 'string':
return ValueClass.String;
case 'symbol':
return ValueClass.Symbol;
case 'object':
if (Record.isRecord<Value<T>, Tuple<Value<T>>, T>(v)) {
return ValueClass.Record;
} else if (Array.isArray(v)) {
return ValueClass.Sequence;
} else if (Set.isSet<T>(v)) {
return ValueClass.Set;
} else if (Dictionary.isDictionary<T>(v)) {
return ValueClass.Dictionary;
} else if (Annotated.isAnnotated<T>(v)) {
return ValueClass.Annotated;
} else if (Bytes.isBytes(v)) {
return ValueClass.ByteString;
} else if (Float.isSingle(v)) {
return ValueClass.Float;
} else if (Float.isDouble(v)) {
return ValueClass.Double;
} else {
return ValueClass.Embedded;
}
default:
((_v: never): never => { throw new Error("Internal error"); })(v);
}
}
export const IDENTITY_FOLD = new IdentityFold<any>();
export function fold<T, R>(v: Value<T>, o: FoldMethods<T, R>): R {