From 0517de01ce22070708c83c3c733529e25684de64 Mon Sep 17 00:00:00 2001 From: Kelvin Steiner Date: Mon, 1 Aug 2022 16:36:37 -0300 Subject: [PATCH] export tag; renaming functions renaming `flatten_enum` to `extract_variant` and `flatten_enum_old` to `flatten_enum` --- src/enum.ts | 18 ++++++++++-------- src/example.ts | 51 +++++++++++++++++++++++++++----------------------- src/index.ts | 14 ++++++++------ src/tag.ts | 4 ++-- 4 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/enum.ts b/src/enum.ts index 12c0452..1cca748 100644 --- a/src/enum.ts +++ b/src/enum.ts @@ -6,18 +6,20 @@ export type Variant = { [x in Tag]: T } export type TagVariants = { [K in keyof T]: Variant } export type Enum = TagVariants[keyof T] -export type FlatVariant = { $: Tag; val: T } -export type FlatEnum = { [K in keyof T]: FlatVariant }[keyof T] +export type ExtractVariant = { $: Tag; val: T } +export type ExtractVariants = { + [K in keyof T]: ExtractVariant +}[keyof T] export type VariantsFrom = AllFields -export type FlatEnumFrom = FlatEnum> +export type FlatEnumFrom = ExtractVariants> -export type FlatVariantOld = { $: Tag } & T -export type FlatEnumOld = { - [K in keyof T]: FlatVariantOld +export type FlatVariant = { $: Tag } & T +export type FlatEnum = { + [K in keyof T]: FlatVariant }[keyof T] -export function flatten_enum_old(value: Enum): FlatEnumOld { +export function flatten_enum(value: Enum): FlatEnum { for (let key in value) { // TODO: use Object.keys if (key !== "$") { @@ -29,7 +31,7 @@ export function flatten_enum_old(value: Enum): FlatEnumOld { throw new Error(`Variant is empty: '${value}'.`) } -export function flatten_enum(value: E): FlatEnumFrom { +export function extract_variant(value: E): FlatEnumFrom { for (let key in value) { // TODO: use Object.keys let _result = value[key] diff --git a/src/example.ts b/src/example.ts index 5e721ab..0fa064b 100644 --- a/src/example.ts +++ b/src/example.ts @@ -1,5 +1,10 @@ import type { Enum } from "." -import { flatten_enum, flatten_enum_f, match, if_let } from "." +import { + extract_variant, + extract_variant_f, + match, + if_let, +} from "." type Stuff = Enum<{ Color: Color @@ -20,11 +25,26 @@ function example() { const a: Stuff = { Color: { r: 10, g: 20, b: 35 } } const b: Stuff = { BW: { value: true } } - const all: Stuff[] = [a, b] + const items: Stuff[] = [a, b] - for (const _elem of all) { - console.log(`Matching with flatten_enum...`) - const variant = flatten_enum(_elem) + console.log(`Matching with 'match'...`) + for (const elem of items) { + match(elem)({ + Color: (color) => console.log(color.r + color.g + color.b), + BW: (bw) => console.log(bw.value), + }) + } + + console.log(`Matching with 'if_let'...`) + for (const elem of items) { + if_let(elem)("Color")((color) => + console.log(`This is color: R:${color.r} G:${color.g} B:${color.b}`) + )(() => console.log(`This is not color: ${elem}`)) + } + + console.log(`Matching with 'extract_variant'...`) + for (const _elem of items) { + const variant = extract_variant(_elem) switch (variant.$) { case "Color": const color = variant.val @@ -39,9 +59,9 @@ function example() { } } - for (const elem of all) { - console.log(`Matching with flatten_enum_f...`) - flatten_enum_f(elem)(({ $, val }) => { + console.log(`Matching with 'extract_variant_f'...`) + for (const elem of items) { + extract_variant_f(elem)(({ $, val }) => { switch ($) { case "Color": console.log(`R: ${val.r}, G: ${val.b} + B: ${val.g}`) @@ -54,21 +74,6 @@ function example() { } }) } - - for (const elem of all) { - console.log(`Matching with map_enum...`) - match(elem)({ - Color: (color) => console.log(color.r + color.g + color.b), - BW: (bw) => console.log(bw.value), - }) - } - - for (const elem of all) { - console.log(`Matching with if_let...`) - if_let(elem)("Color")((color) => - console.log(`This is color: R:${color.r} G:${color.g} B:${color.b}`) - )(() => console.log(`This is not color: ${elem}`)) - } } example() diff --git a/src/index.ts b/src/index.ts index a118d22..e96bad4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,22 +1,24 @@ import type { FlatEnumFrom, VariantsFrom } from "./enum" -import { flatten_enum } from "./enum" +import { extract_variant } from "./enum" export type { Enum } from "./enum" -export { flatten_enum } from "./enum" +export { extract_variant, flatten_enum } from "./enum" + +export { Tag, Tagged } from './tag' export type Option = T | null -export const flatten_enum_f = +export const extract_variant_f = (value: N) => (f: (v: FlatEnumFrom) => R) => - f(flatten_enum(value)) + f(extract_variant(value)) type MatchDict = { [tag in keyof V]: (v: V[tag]) => R } export const match = (value: N) => (matcher: MatchDict, R>): R => - flatten_enum_f(value)(({ $, val }) => { + extract_variant_f(value)(({ $, val }) => { let arm = matcher[$] return arm(val) }) @@ -26,4 +28,4 @@ export const if_let = >(tag: K) => (th: (v: VariantsFrom[K]) => R) => (el: () => R): R => - flatten_enum_f(value)(({ $, val }) => ($ === tag ? th(val) : el())) + extract_variant_f(value)(({ $, val }) => ($ === tag ? th(val) : el())) diff --git a/src/tag.ts b/src/tag.ts index a5b21db..4de6ef5 100644 --- a/src/tag.ts +++ b/src/tag.ts @@ -1,4 +1,4 @@ -declare const TAG: unique symbol -export type Tag = { readonly [TAG]: T } +declare const TAG_KEY: unique symbol +export type Tag = { readonly [TAG_KEY]: T } export type Tagged = Tag & V