From 3f5022ee39ed587fb69cc7f0f0f65001387208a1 Mon Sep 17 00:00:00 2001 From: Rachel Barrett Date: Sat, 10 Sep 2022 14:45:25 +0100 Subject: [PATCH 1/8] Initial commit --- src/Variant.ts | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/Variant.ts diff --git a/src/Variant.ts b/src/Variant.ts new file mode 100644 index 000000000..57a8912cb --- /dev/null +++ b/src/Variant.ts @@ -0,0 +1,95 @@ +// ## type + +const tagFieldName = "_tag" +const valueFieldName = "value" + +export type Tagged = { + [tagFieldName]: Tag + [valueFieldName]: A +} + +export function tagged( + tag: Tag, + value: A +): Tagged { + return { [tagFieldName]: tag, [valueFieldName]: value } +} + +export type Variant = { + [Key in keyof Map]: Tagged +}[keyof Map] + +export type Map> = { + [Key in Variant[typeof tagFieldName]]: (Variant & { + [tagFieldName]: Key + })[typeof valueFieldName] +} + +// ## module + +// This is the same as type Module> = Cases; +// but writing it inline to give better type descriptions +export type Module> = { + [Key in keyof Map]: (value: Map[Key]) => Variant +} + +// this is an identity function that just exists to give better type descriptions +export function module>( + constructors: Module +): Module { + return constructors +} + +// arguments are split to allow partial type inference +// Note this function is only type safe with a true variant, not the super type Tagged + +export function caseOf, A>( + cases: Cases +): (variant: Variant) => A { + return (variant) => match(variant)(cases) +} + +export function match>( + variant: Variant +): (cases: Cases) => A { + return (cases) => + (cases as Record)[variant[tagFieldName]]( + variant[valueFieldName] + ) +} + +export function caseOfWithDefault( + defaultValue: A +): >( + partialCases: Partial> +) => (variant: Variant) => A { + return (partialCases) => (variant) => + matchWithDefault(variant)(defaultValue)(partialCases) +} + +export function matchWithDefault>( + variant: Variant +): (defaultValue: A) => (partialCases: Partial>) => A { + return (defaultValue) => (partialCases) => { + const caseFunction = (partialCases as Record)[ + variant[tagFieldName] + ] + return caseFunction ? caseFunction(variant[valueFieldName]) : defaultValue + } +} + +export type Cases, A> = { + [Key in keyof Map]: (value: Map[Key]) => A +} + +// this is isomorphic to the variant type +export type Match, A> = ( + cases: Cases +) => A + +export type TagsOf> = keyof Map + +export type TypeForTag< + Variant extends Tagged, + Key extends keyof Map +> = Map[Key] From e1cd8f588a1c3bc8e25bdfa78ddb420d87688215 Mon Sep 17 00:00:00 2001 From: Rachel Barrett Date: Sat, 10 Sep 2022 18:49:49 +0100 Subject: [PATCH 2/8] Add documentation comments in the same style as the rest of fp-ts --- src/Variant.ts | 146 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 129 insertions(+), 17 deletions(-) diff --git a/src/Variant.ts b/src/Variant.ts index 57a8912cb..107453214 100644 --- a/src/Variant.ts +++ b/src/Variant.ts @@ -1,54 +1,139 @@ -// ## type +/** + * ```ts + * type Tagged = {_tag: Tag, value: A} + * ``` + * + * is a type for a tagged value which when used together in a union can represent a Variant type + * (aka sum type / discriminated union). + * + * Variant types are dual to Record types. Unlike Record types which have multiple keys all of which have to be provided, + * a value of a Variant type represents one of a number of cases. + * + * The most common thing we want to do with Variant Types is pattern match on the case; + * Given a record of functions, one for each case, we can use the function `caseOf` to pattern match + * a value of a Variant and apply the function for the correct case. + * + * @example + * + * import * as variant from "fp-ts/Variant" + * import { pipe } from "fp-ts/function" + * + * type Media = + * | variant.Tagged<"book", number> + * | variant.Tagged<"film", string> + * | variant.Tagged<"song", string> + * + * const Media = variant.module({ + * book: (value: number) => variant.tagged(_book, value), + * film: (value: string) => variant.tagged(_film, value), + * song: (value: string) => variant.tagged(_song, value), + * }) + * + * const _book = "book" + * const _film = "film" + * const _song = "song" + * + * const exampleBook = Media.book(123) + * const exampleFilm = Media.film("Harry Potter") + * + * const isBook: (media: Media) => boolean = (media) => + * pipe( + * media, + * variant.caseOfWithDefault(false)({ + * [_book]: () => true, + * }) + * ) + * + * assert.deepStrictEqual(isBook(exampleBook), true) + * assert.deepStrictEqual(isBook(exampleFilm), false) + * + */ + +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- const tagFieldName = "_tag" const valueFieldName = "value" +/** + * A type which represents a case in a variant + * @category model + */ export type Tagged = { [tagFieldName]: Tag [valueFieldName]: A } -export function tagged( - tag: Tag, - value: A -): Tagged { - return { [tagFieldName]: tag, [valueFieldName]: value } -} - +/** + * Type constructor of a variant type from the dual record type + * @category model + */ export type Variant = { [Key in keyof Map]: Tagged }[keyof Map] +/** + * Type constructor of a record type from the dual variant type + * @category model + */ export type Map> = { [Key in Variant[typeof tagFieldName]]: (Variant & { [tagFieldName]: Key })[typeof valueFieldName] } -// ## module +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- -// This is the same as type Module> = Cases; -// but writing it inline to give better type descriptions -export type Module> = { - [Key in keyof Map]: (value: Map[Key]) => Variant +/** + * Constructs a value of a Variant with the given tag + * @category constructors + */ +export function tagged( + tag: Tag, + value: A +): Tagged { + return { [tagFieldName]: tag, [valueFieldName]: value } } -// this is an identity function that just exists to give better type descriptions +/** + * Groups together all the variant constructors in a "module" + * @category constructors + */ export function module>( constructors: Module ): Module { return constructors } -// arguments are split to allow partial type inference -// Note this function is only type safe with a true variant, not the super type Tagged +/** + * The type of the "Module" constructed in the above function + * @category constructors + */ +export type Module> = { + [Key in keyof Map]: (value: Map[Key]) => Variant +} +// ------------------------------------------------------------------------------------- +// destructors +// ------------------------------------------------------------------------------------- + +/** + * Pattern matching on a variant where all cases are provided + * @category destructors + */ export function caseOf, A>( cases: Cases ): (variant: Variant) => A { return (variant) => match(variant)(cases) } +/** + * Pattern matching on a variant where all cases are provided, with arguments swapped + * @category destructors + */ export function match>( variant: Variant ): (cases: Cases) => A { @@ -58,6 +143,10 @@ export function match>( ) } +/** + * Pattern matching on a variant with a default case + * @category destructors + */ export function caseOfWithDefault( defaultValue: A ): >( @@ -67,6 +156,10 @@ export function caseOfWithDefault( matchWithDefault(variant)(defaultValue)(partialCases) } +/** + * Pattern matching on a variant with a default case, with arguments swapped + * @category destructors + */ export function matchWithDefault>( variant: Variant ): (defaultValue: A) => (partialCases: Partial>) => A { @@ -78,17 +171,36 @@ export function matchWithDefault>( } } +// ------------------------------------------------------------------------------------- +// Type helpers +// ------------------------------------------------------------------------------------- + +/** + * Type of the record supplied for pattern matching + * @category model + */ export type Cases, A> = { [Key in keyof Map]: (value: Map[Key]) => A } -// this is isomorphic to the variant type +/** + * Type of the pattern matching function, isomorphic to the variant type + * @category model + */ export type Match, A> = ( cases: Cases ) => A +/** + * Type of the tags of a variant + * @category model + */ export type TagsOf> = keyof Map +/** + * Type of the variant at a particular tag. + * @category model + */ export type TypeForTag< Variant extends Tagged, Key extends keyof Map From 0ee8045f3459707ff52b5ebcbd75015b11400be7 Mon Sep 17 00:00:00 2001 From: Rachel Barrett Date: Sat, 10 Sep 2022 19:00:01 +0100 Subject: [PATCH 3/8] Add variant to the index --- src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.ts b/src/index.ts index ede7b0a7c..508c49981 100644 --- a/src/index.ts +++ b/src/index.ts @@ -118,6 +118,7 @@ import * as tree from './Tree' import * as tuple from './Tuple' import * as unfoldable from './Unfoldable' import * as validationT from './ValidationT' +import * as variant from "./Variant" import * as void_ from './void' import * as witherable from './Witherable' import * as writer from './Writer' @@ -588,6 +589,7 @@ export { * @since 2.0.0 */ validationT, + variant, /** * @since 2.11.0 */ From 156705d002c330c5e3ae5b27967763de3a49048c Mon Sep 17 00:00:00 2001 From: Rachel Barrett Date: Sat, 10 Sep 2022 19:27:37 +0100 Subject: [PATCH 4/8] Run prettier --- src/Variant.ts | 66 +++++++++++++++++--------------------------------- src/index.ts | 2 +- 2 files changed, 23 insertions(+), 45 deletions(-) diff --git a/src/Variant.ts b/src/Variant.ts index 107453214..93e8170e4 100644 --- a/src/Variant.ts +++ b/src/Variant.ts @@ -2,40 +2,40 @@ * ```ts * type Tagged = {_tag: Tag, value: A} * ``` - * + * * is a type for a tagged value which when used together in a union can represent a Variant type * (aka sum type / discriminated union). * * Variant types are dual to Record types. Unlike Record types which have multiple keys all of which have to be provided, * a value of a Variant type represents one of a number of cases. - * + * * The most common thing we want to do with Variant Types is pattern match on the case; - * Given a record of functions, one for each case, we can use the function `caseOf` to pattern match + * Given a record of functions, one for each case, we can use the function `caseOf` to pattern match * a value of a Variant and apply the function for the correct case. - * + * * @example - * + * * import * as variant from "fp-ts/Variant" * import { pipe } from "fp-ts/function" - * + * * type Media = * | variant.Tagged<"book", number> * | variant.Tagged<"film", string> * | variant.Tagged<"song", string> - * + * * const Media = variant.module({ * book: (value: number) => variant.tagged(_book, value), * film: (value: string) => variant.tagged(_film, value), * song: (value: string) => variant.tagged(_song, value), * }) - * + * * const _book = "book" * const _film = "film" * const _song = "song" - * + * * const exampleBook = Media.book(123) * const exampleFilm = Media.film("Harry Potter") - * + * * const isBook: (media: Media) => boolean = (media) => * pipe( * media, @@ -53,8 +53,8 @@ // model // ------------------------------------------------------------------------------------- -const tagFieldName = "_tag" -const valueFieldName = "value" +const tagFieldName = '_tag' +const valueFieldName = 'value' /** * A type which represents a case in a variant @@ -91,10 +91,7 @@ export type Map> = { * Constructs a value of a Variant with the given tag * @category constructors */ -export function tagged( - tag: Tag, - value: A -): Tagged { +export function tagged(tag: Tag, value: A): Tagged { return { [tagFieldName]: tag, [valueFieldName]: value } } @@ -102,9 +99,7 @@ export function tagged( * Groups together all the variant constructors in a "module" * @category constructors */ -export function module>( - constructors: Module -): Module { +export function module>(constructors: Module): Module { return constructors } @@ -124,9 +119,7 @@ export type Module> = { * Pattern matching on a variant where all cases are provided * @category destructors */ -export function caseOf, A>( - cases: Cases -): (variant: Variant) => A { +export function caseOf, A>(cases: Cases): (variant: Variant) => A { return (variant) => match(variant)(cases) } @@ -134,13 +127,8 @@ export function caseOf, A>( * Pattern matching on a variant where all cases are provided, with arguments swapped * @category destructors */ -export function match>( - variant: Variant -): (cases: Cases) => A { - return (cases) => - (cases as Record)[variant[tagFieldName]]( - variant[valueFieldName] - ) +export function match>(variant: Variant): (cases: Cases) => A { + return (cases) => (cases as Record)[variant[tagFieldName]](variant[valueFieldName]) } /** @@ -149,11 +137,8 @@ export function match>( */ export function caseOfWithDefault( defaultValue: A -): >( - partialCases: Partial> -) => (variant: Variant) => A { - return (partialCases) => (variant) => - matchWithDefault(variant)(defaultValue)(partialCases) +): >(partialCases: Partial>) => (variant: Variant) => A { + return (partialCases) => (variant) => matchWithDefault(variant)(defaultValue)(partialCases) } /** @@ -164,9 +149,7 @@ export function matchWithDefault>( variant: Variant ): (defaultValue: A) => (partialCases: Partial>) => A { return (defaultValue) => (partialCases) => { - const caseFunction = (partialCases as Record)[ - variant[tagFieldName] - ] + const caseFunction = (partialCases as Record)[variant[tagFieldName]] return caseFunction ? caseFunction(variant[valueFieldName]) : defaultValue } } @@ -187,9 +170,7 @@ export type Cases, A> = { * Type of the pattern matching function, isomorphic to the variant type * @category model */ -export type Match, A> = ( - cases: Cases -) => A +export type Match, A> = (cases: Cases) => A /** * Type of the tags of a variant @@ -201,7 +182,4 @@ export type TagsOf> = keyof Map * Type of the variant at a particular tag. * @category model */ -export type TypeForTag< - Variant extends Tagged, - Key extends keyof Map -> = Map[Key] +export type TypeForTag, Key extends keyof Map> = Map[Key] diff --git a/src/index.ts b/src/index.ts index 508c49981..335f70189 100644 --- a/src/index.ts +++ b/src/index.ts @@ -118,7 +118,7 @@ import * as tree from './Tree' import * as tuple from './Tuple' import * as unfoldable from './Unfoldable' import * as validationT from './ValidationT' -import * as variant from "./Variant" +import * as variant from './Variant' import * as void_ from './void' import * as witherable from './Witherable' import * as writer from './Writer' From d67fa1a14481262f7a102bcc2db775ccf89f890e Mon Sep 17 00:00:00 2001 From: Rachel Barrett Date: Sat, 10 Sep 2022 19:38:02 +0100 Subject: [PATCH 5/8] Add test file --- test/Variant.ts | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 test/Variant.ts diff --git a/test/Variant.ts b/test/Variant.ts new file mode 100644 index 000000000..6350b2912 --- /dev/null +++ b/test/Variant.ts @@ -0,0 +1,47 @@ +import * as U from './util' +import { pipe } from '../src/function' +import * as _ from '../src/Variant' + +type Media = _.Tagged<'book', number> | _.Tagged<'film', string> | _.Tagged<'song', string> + +const Media = _.module({ + book: (value) => _.tagged(_book, value), + film: (value) => _.tagged(_film, value), + song: (value) => _.tagged(_song, value) +}) + +const _book = 'book' +const _film = 'film' +const _song = 'song' + +const show: (media: Media) => string = (media) => + pipe( + media, + _.caseOf({ + [_book]: (isbn) => `Book ${isbn}`, + [_film]: (filmTitle) => `Film ${filmTitle}`, + [_song]: (song) => `Song ${song}` + }) + ) + +const isBook: (media: Media) => boolean = (media) => pipe(media, _.caseOfWithDefault(false)({ [_book]: () => true })) + +const bookExample = Media.book(123) +const filmExample = Media.film('Harry Potter') + +describe('Variant', () => { + describe('constructors', () => { + it('tagged', () => { + U.deepStrictEqual(_.tagged('test tag', 1), { _tag: 'test tag', value: 1 }) + }) + }) + describe('destructors', () => { + it('caseOf', () => { + U.strictEqual(show(bookExample), 'Book 123') + }) + it('caseOfWithDefault', () => { + U.strictEqual(isBook(bookExample), true) + U.strictEqual(isBook(filmExample), false) + }) + }) +}) From e7fc12d780ca36a6041eea3c8c33befc176def5b Mon Sep 17 00:00:00 2001 From: Rachel Barrett Date: Sat, 10 Sep 2022 20:13:59 +0100 Subject: [PATCH 6/8] Add @since doc tags --- docs/modules/Witherable.ts.md | 2 +- docs/modules/Writer.ts.md | 2 +- docs/modules/WriterT.ts.md | 2 +- docs/modules/Zero.ts.md | 2 +- docs/modules/index.ts.md | 11 +++++++++++ docs/modules/void.ts.md | 2 +- src/Variant.ts | 15 +++++++++++++++ src/index.ts | 3 +++ 8 files changed, 34 insertions(+), 5 deletions(-) diff --git a/docs/modules/Witherable.ts.md b/docs/modules/Witherable.ts.md index e3e6ffda5..da5805f2b 100644 --- a/docs/modules/Witherable.ts.md +++ b/docs/modules/Witherable.ts.md @@ -1,6 +1,6 @@ --- title: Witherable.ts -nav_order: 120 +nav_order: 121 parent: Modules --- diff --git a/docs/modules/Writer.ts.md b/docs/modules/Writer.ts.md index 57b74116a..351f70ade 100644 --- a/docs/modules/Writer.ts.md +++ b/docs/modules/Writer.ts.md @@ -1,6 +1,6 @@ --- title: Writer.ts -nav_order: 121 +nav_order: 122 parent: Modules --- diff --git a/docs/modules/WriterT.ts.md b/docs/modules/WriterT.ts.md index 0da38a457..917261dad 100644 --- a/docs/modules/WriterT.ts.md +++ b/docs/modules/WriterT.ts.md @@ -1,6 +1,6 @@ --- title: WriterT.ts -nav_order: 122 +nav_order: 123 parent: Modules --- diff --git a/docs/modules/Zero.ts.md b/docs/modules/Zero.ts.md index 494cc43ab..c3dac2096 100644 --- a/docs/modules/Zero.ts.md +++ b/docs/modules/Zero.ts.md @@ -1,6 +1,6 @@ --- title: Zero.ts -nav_order: 123 +nav_order: 124 parent: Modules --- diff --git a/docs/modules/index.ts.md b/docs/modules/index.ts.md index 77372f0ad..f57a0a977 100644 --- a/docs/modules/index.ts.md +++ b/docs/modules/index.ts.md @@ -129,6 +129,7 @@ Added in v2.0.0 - [tuple](#tuple) - [unfoldable](#unfoldable) - [validationT](#validationt) + - [variant](#variant) - [void](#void) - [witherable](#witherable) - [writer](#writer) @@ -1299,6 +1300,16 @@ export declare const validationT: typeof validationT Added in v2.0.0 +## variant + +**Signature** + +```ts +export declare const variant: typeof variant +``` + +Added in v2.12.4 + ## void **Signature** diff --git a/docs/modules/void.ts.md b/docs/modules/void.ts.md index cc1ab2757..668c6d301 100644 --- a/docs/modules/void.ts.md +++ b/docs/modules/void.ts.md @@ -1,6 +1,6 @@ --- title: void.ts -nav_order: 119 +nav_order: 120 parent: Modules --- diff --git a/src/Variant.ts b/src/Variant.ts index 93e8170e4..08b4d93d6 100644 --- a/src/Variant.ts +++ b/src/Variant.ts @@ -47,6 +47,7 @@ * assert.deepStrictEqual(isBook(exampleBook), true) * assert.deepStrictEqual(isBook(exampleFilm), false) * + * @since 2.12.4 */ // ------------------------------------------------------------------------------------- @@ -59,6 +60,7 @@ const valueFieldName = 'value' /** * A type which represents a case in a variant * @category model + * @since 2.12.4 */ export type Tagged = { [tagFieldName]: Tag @@ -68,6 +70,7 @@ export type Tagged = { /** * Type constructor of a variant type from the dual record type * @category model + * @since 2.12.4 */ export type Variant = { [Key in keyof Map]: Tagged @@ -76,6 +79,7 @@ export type Variant = { /** * Type constructor of a record type from the dual variant type * @category model + * @since 2.12.4 */ export type Map> = { [Key in Variant[typeof tagFieldName]]: (Variant & { @@ -90,6 +94,7 @@ export type Map> = { /** * Constructs a value of a Variant with the given tag * @category constructors + * @since 2.12.4 */ export function tagged(tag: Tag, value: A): Tagged { return { [tagFieldName]: tag, [valueFieldName]: value } @@ -98,6 +103,7 @@ export function tagged(tag: Tag, value: A): Tagged>(constructors: Module): Module { return constructors @@ -106,6 +112,7 @@ export function module>(constructors: Module /** * The type of the "Module" constructed in the above function * @category constructors + * @since 2.12.4 */ export type Module> = { [Key in keyof Map]: (value: Map[Key]) => Variant @@ -118,6 +125,7 @@ export type Module> = { /** * Pattern matching on a variant where all cases are provided * @category destructors + * @since 2.12.4 */ export function caseOf, A>(cases: Cases): (variant: Variant) => A { return (variant) => match(variant)(cases) @@ -126,6 +134,7 @@ export function caseOf, A>(cases: Cases>(variant: Variant): (cases: Cases) => A { return (cases) => (cases as Record)[variant[tagFieldName]](variant[valueFieldName]) @@ -134,6 +143,7 @@ export function match>(variant: Variant): ( defaultValue: A @@ -144,6 +154,7 @@ export function caseOfWithDefault( /** * Pattern matching on a variant with a default case, with arguments swapped * @category destructors + * @since 2.12.4 */ export function matchWithDefault>( variant: Variant @@ -161,6 +172,7 @@ export function matchWithDefault>( /** * Type of the record supplied for pattern matching * @category model + * @since 2.12.4 */ export type Cases, A> = { [Key in keyof Map]: (value: Map[Key]) => A @@ -169,17 +181,20 @@ export type Cases, A> = { /** * Type of the pattern matching function, isomorphic to the variant type * @category model + * @since 2.12.4 */ export type Match, A> = (cases: Cases) => A /** * Type of the tags of a variant * @category model + * @since 2.12.4 */ export type TagsOf> = keyof Map /** * Type of the variant at a particular tag. * @category model + * @since 2.12.4 */ export type TypeForTag, Key extends keyof Map> = Map[Key] diff --git a/src/index.ts b/src/index.ts index 335f70189..1b4207156 100644 --- a/src/index.ts +++ b/src/index.ts @@ -589,6 +589,9 @@ export { * @since 2.0.0 */ validationT, + /** + * @since 2.12.4 + */ variant, /** * @since 2.11.0 From 09e13d33f37524c57e085d136aa58c4a68d4334b Mon Sep 17 00:00:00 2001 From: Rachel Barrett Date: Sat, 10 Sep 2022 20:37:59 +0100 Subject: [PATCH 7/8] Add Variant documentation --- docs/modules/Variant.ts.md | 273 +++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 docs/modules/Variant.ts.md diff --git a/docs/modules/Variant.ts.md b/docs/modules/Variant.ts.md new file mode 100644 index 000000000..05dbaa00b --- /dev/null +++ b/docs/modules/Variant.ts.md @@ -0,0 +1,273 @@ +--- +title: Variant.ts +nav_order: 119 +parent: Modules +--- + +## Variant overview + +```ts +type Tagged = { _tag: Tag; value: A } +``` + +is a type for a tagged value which when used together in a union can represent a Variant type +(aka sum type / discriminated union). + +Variant types are dual to Record types. Unlike Record types which have multiple keys all of which have to be provided, +a value of a Variant type represents one of a number of cases. + +The most common thing we want to do with Variant Types is pattern match on the case; +Given a record of functions, one for each case, we can use the function `caseOf` to pattern match +a value of a Variant and apply the function for the correct case. + +**Example** + +```ts +import * as variant from 'fp-ts/Variant' +import { pipe } from 'fp-ts/function' + +type Media = variant.Tagged<'book', number> | variant.Tagged<'film', string> | variant.Tagged<'song', string> + +const Media = variant.module({ + book: (value: number) => variant.tagged(_book, value), + film: (value: string) => variant.tagged(_film, value), + song: (value: string) => variant.tagged(_song, value), +}) + +const _book = 'book' +const _film = 'film' +const _song = 'song' + +const exampleBook = Media.book(123) +const exampleFilm = Media.film('Harry Potter') + +const isBook: (media: Media) => boolean = (media) => + pipe( + media, + variant.caseOfWithDefault(false)({ + [_book]: () => true, + }) + ) + +assert.deepStrictEqual(isBook(exampleBook), true) +assert.deepStrictEqual(isBook(exampleFilm), false) +``` + +Added in v2.12.4 + +--- + +

Table of contents

+ +- [constructors](#constructors) + - [Module (type alias)](#module-type-alias) + - [module](#module) + - [tagged](#tagged) +- [destructors](#destructors) + - [caseOf](#caseof) + - [caseOfWithDefault](#caseofwithdefault) + - [match](#match) + - [matchWithDefault](#matchwithdefault) +- [model](#model) + - [Cases (type alias)](#cases-type-alias) + - [Map (type alias)](#map-type-alias) + - [Match (type alias)](#match-type-alias) + - [Tagged (type alias)](#tagged-type-alias) + - [TagsOf (type alias)](#tagsof-type-alias) + - [TypeForTag (type alias)](#typefortag-type-alias) + - [Variant (type alias)](#variant-type-alias) + +--- + +# constructors + +## Module (type alias) + +The type of the "Module" constructed in the above function + +**Signature** + +```ts +export type Module> = { + [Key in keyof Map]: (value: Map[Key]) => Variant +} +``` + +Added in v2.12.4 + +## module + +Groups together all the variant constructors in a "module" + +**Signature** + +```ts +export declare function module>(constructors: Module): Module +``` + +Added in v2.12.4 + +## tagged + +Constructs a value of a Variant with the given tag + +**Signature** + +```ts +export declare function tagged(tag: Tag, value: A): Tagged +``` + +Added in v2.12.4 + +# destructors + +## caseOf + +Pattern matching on a variant where all cases are provided + +**Signature** + +```ts +export declare function caseOf, A>( + cases: Cases +): (variant: Variant) => A +``` + +Added in v2.12.4 + +## caseOfWithDefault + +Pattern matching on a variant with a default case + +**Signature** + +```ts +export declare function caseOfWithDefault
( + defaultValue: A +): >(partialCases: Partial>) => (variant: Variant) => A +``` + +Added in v2.12.4 + +## match + +Pattern matching on a variant where all cases are provided, with arguments swapped + +**Signature** + +```ts +export declare function match>(variant: Variant): (cases: Cases) => A +``` + +Added in v2.12.4 + +## matchWithDefault + +Pattern matching on a variant with a default case, with arguments swapped + +**Signature** + +```ts +export declare function matchWithDefault>( + variant: Variant +): (defaultValue: A) => (partialCases: Partial>) => A +``` + +Added in v2.12.4 + +# model + +## Cases (type alias) + +Type of the record supplied for pattern matching + +**Signature** + +```ts +export type Cases, A> = { + [Key in keyof Map]: (value: Map[Key]) => A +} +``` + +Added in v2.12.4 + +## Map (type alias) + +Type constructor of a record type from the dual variant type + +**Signature** + +```ts +export type Map> = { + [Key in Variant[typeof tagFieldName]]: (Variant & { + [tagFieldName]: Key + })[typeof valueFieldName] +} +``` + +Added in v2.12.4 + +## Match (type alias) + +Type of the pattern matching function, isomorphic to the variant type + +**Signature** + +```ts +export type Match, A> = (cases: Cases) => A +``` + +Added in v2.12.4 + +## Tagged (type alias) + +A type which represents a case in a variant + +**Signature** + +```ts +export type Tagged = { + [tagFieldName]: Tag + [valueFieldName]: A +} +``` + +Added in v2.12.4 + +## TagsOf (type alias) + +Type of the tags of a variant + +**Signature** + +```ts +export type TagsOf> = keyof Map +``` + +Added in v2.12.4 + +## TypeForTag (type alias) + +Type of the variant at a particular tag. + +**Signature** + +```ts +export type TypeForTag, Key extends keyof Map> = Map[Key] +``` + +Added in v2.12.4 + +## Variant (type alias) + +Type constructor of a variant type from the dual record type + +**Signature** + +```ts +export type Variant = { + [Key in keyof Map]: Tagged +}[keyof Map] +``` + +Added in v2.12.4 From 8b870c00340a46d2ef08baa3835731fd1b534176 Mon Sep 17 00:00:00 2001 From: Rachel Barrett Date: Sat, 10 Sep 2022 20:46:08 +0100 Subject: [PATCH 8/8] tweak to variant documentation --- docs/modules/Variant.ts.md | 2 +- src/Variant.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/modules/Variant.ts.md b/docs/modules/Variant.ts.md index 05dbaa00b..9671d9cf6 100644 --- a/docs/modules/Variant.ts.md +++ b/docs/modules/Variant.ts.md @@ -83,7 +83,7 @@ Added in v2.12.4 ## Module (type alias) -The type of the "Module" constructed in the above function +The type of the "module" of variant constructors **Signature** diff --git a/src/Variant.ts b/src/Variant.ts index 08b4d93d6..7d37158cd 100644 --- a/src/Variant.ts +++ b/src/Variant.ts @@ -110,7 +110,7 @@ export function module>(constructors: Module } /** - * The type of the "Module" constructed in the above function + * The type of the "module" of variant constructors * @category constructors * @since 2.12.4 */