├── .npmignore
├── .nvmrc
├── .huskyrc
├── .lintstagedrc
├── tsconfig.json
├── mocharc.json
├── src
├── Typeclass
│ ├── Bounded.ts
│ ├── ForEach
│ │ ├── index.ts
│ │ └── ForEach.test.ts
│ ├── Commutative.ts
│ ├── Inverse.ts
│ ├── Concat.ts
│ ├── Eq.test.ts
│ ├── Identity.test.ts
│ ├── Associative.test.ts
│ ├── Concat.test.ts
│ ├── Inverse.test.ts
│ ├── index.ts
│ ├── Associative.ts
│ ├── CommutativeBoth.ts
│ ├── CommutativeEither.ts
│ ├── Compactable.ts
│ ├── Identity.ts
│ ├── IdentityFlatten.ts
│ ├── IdentityEither.ts
│ └── Debug.ts
├── Json.ts
├── Law
│ ├── Inverse.ts
│ ├── Associative.ts
│ ├── Commutative.ts
│ ├── index.ts
│ ├── Identity.ts
│ ├── AssociativeBoth.ts
│ ├── Eq.ts
│ ├── Ord.ts
│ └── ForEach.ts
├── logical.ts
├── string.test.ts
├── boolean.test.ts
├── Progress.test.ts
├── Id.ts
├── Match.ts
├── Endomorphism.ts
├── number.test.ts
├── index.ts
├── common.ts
├── struct.ts
├── Predicate.test.ts
├── Progress.ts
├── Refinement.ts
├── Unary.ts
├── Predicate.ts
├── Either.test.ts
├── function.test.ts
├── boolean.ts
├── DataEither.test.ts
└── string.ts
├── tools
├── overloads
│ ├── tsconfig.json
│ ├── definitions
│ │ ├── CommutativeBoth.ts
│ │ ├── Compactable.ts
│ │ ├── CommutativeEither.ts
│ │ ├── IdentityBoth.ts
│ │ ├── IdentityFlatten.ts
│ │ ├── IdentityEither.ts
│ │ ├── Identity.ts
│ │ ├── FoldMap.size.ts
│ │ ├── FoldMap.isEmpty.ts
│ │ ├── FoldMap.isNonEmpty.ts
│ │ ├── Top.ts
│ │ ├── Bottom.ts
│ │ ├── FoldMap.addIndex.ts
│ │ ├── Top.top.ts
│ │ ├── FilterMap.map.ts
│ │ ├── FoldMap.reverse.ts
│ │ ├── Compact.ts
│ │ ├── FoldMap.toArray.ts
│ │ ├── PartitionMap.separate.ts
│ │ ├── Covariant.tupled.ts
│ │ ├── Bottom.bottom.ts
│ │ ├── AssociativeFlatten.ts
│ │ ├── AssociativeEither.eventually.ts
│ │ ├── FoldMap.reduceIdentity.ts
│ │ ├── AssociativeFlatten.makeAssociativeBoth.ts
│ │ ├── FoldMap.foldLeft.ts
│ │ ├── Covariant.mapTo.ts
│ │ ├── FoldMap.reduceAssociative.ts
│ │ ├── FoldMap.reduceCommutative.ts
│ │ ├── FilterMap.compact.ts
│ │ ├── Top.makeFromValue.ts
│ │ ├── FoldMapWithIndex.foldMap.ts
│ │ ├── AssociativeBoth.zipLeft.ts
│ │ ├── AssociativeBoth.zipRight.ts
│ │ ├── FoldMap.some.ts
│ │ ├── Contravariant.ts
│ │ ├── FoldMap.every.ts
│ │ ├── Law
│ │ │ ├── testAllHKTLaws.ts
│ │ │ ├── testCovariant.ts
│ │ │ ├── testFilterMap.ts
│ │ │ ├── testCovariantIdentityFlatten.ts
│ │ │ ├── testCovariantIdentityBoth.ts
│ │ │ ├── testCovariantAssociativeEither.ts
│ │ │ ├── testCovariantAssociativeFlatten.ts
│ │ │ ├── testCovariantIdentityEither.ts
│ │ │ └── testContravariant.ts
│ │ ├── FoldMap.exists.ts
│ │ ├── FoldMap.intercalate.ts
│ │ ├── Top.makeFromLazy.ts
│ │ ├── Covariant.flap.ts
│ │ ├── FoldMap.count.ts
│ │ ├── FilterMap.ts
│ │ ├── FoldMap.find.ts
│ │ ├── Compact.compact.ts
│ │ ├── Reduce.ts
│ │ ├── Separate.ts
│ │ ├── Identity.fromIdentityEitherCovariant.ts
│ │ ├── FoldMap.reduce.ts
│ │ ├── Covariant.ts
│ │ ├── ReduceRight.ts
│ │ ├── ForEach.foldMap.ts
│ │ ├── FilterMapWithIndex.filterMap.ts
│ │ ├── AssociativeFlatten.flatMap.ts
│ │ ├── Divariant.map.ts
│ │ ├── FoldMap.contains.ts
│ │ ├── Trivariant.map.ts
│ │ ├── ReduceWithIndex.reduce.ts
│ │ ├── AssociativeCompose.ts
│ │ ├── Bicovariant.map.ts
│ │ ├── FoldMap.groupBy.ts
│ │ ├── AssociativeBoth.ts
│ │ ├── Divariant.contramap.ts
│ │ ├── FoldMapWithIndex.toMap.ts
│ │ ├── Bicovariant.mapLeft.ts
│ │ ├── Covariant.bindTo.ts
│ │ ├── FoldMap.ts
│ │ ├── NaturalTransformation.ts
│ │ ├── Invariant.ts
│ │ ├── FoldMap.reduceRight.ts
│ │ ├── Reduce.reduce.ts
│ │ ├── AssociativeFlatten.flatten.ts
│ │ ├── FoldMap.foldMap.ts
│ │ ├── ReduceRightWithIndex.reduceRight.ts
│ │ ├── AssociativeEither.ts
│ │ ├── ReduceRight.reduceRight.ts
│ │ ├── Contravariant.contramap.ts
│ │ ├── AssociativeEither.orElse.ts
│ │ ├── Covariant.map.ts
│ │ ├── Invariant.imap.ts
│ │ ├── Contravariant.contramapC.ts
│ │ ├── ForEach.map.ts
│ │ ├── Trivariant.contramap.ts
│ │ ├── AssociativeEither.tuple.ts
│ │ ├── IdentityBoth.tuple.ts
│ │ ├── AssociativeBoth.both.ts
│ │ ├── FilterMap.filterMap.ts
│ │ ├── Trivariant.bimap.ts
│ │ ├── AssociativeBoth.tuple.ts
│ │ ├── Divariant.ts
│ │ ├── ForEach.sequence.ts
│ │ ├── Bicovariant.ts
│ │ ├── ForEach.mapAccum.ts
│ │ ├── CovariantWithIndex.map.ts
│ │ ├── FoldMapWithIndex.ts
│ │ ├── AssociativeCompose.compose.ts
│ │ ├── FoldMap.partitionMap.ts
│ │ ├── Divariant.dimap.ts
│ │ ├── PartitionMap.ts
│ │ ├── ReduceWithIndex.ts
│ │ ├── AssociativeEither.either.ts
│ │ ├── FilterMapWithIndex.ts
│ │ ├── ReduceRightWithIndex.ts
│ │ ├── AssociativeEither.eitherWith.ts
│ │ ├── ForEach.forEach.ts
│ │ ├── CovariantWithIndex.ts
│ │ ├── Bicovariant.bimap.ts
│ │ ├── AssociativeBoth.bothWith.ts
│ │ ├── PartitionMapWithIndex.ts
│ │ ├── IdentityBoth.struct.ts
│ │ ├── FilterMap.filter.ts
│ │ ├── PartitionMapWithIndex.partitionMap.ts
│ │ ├── AssociativeFlatten.bind.ts
│ │ ├── ForEach.compacted.ts
│ │ ├── ForEach.ts
│ │ ├── ForEachWithIndex.forEach.ts
│ │ ├── Trivariant.ts
│ │ ├── ForEach.separated.ts
│ │ └── ForEachWithIndex.ts
│ ├── findHKTParams.ts
│ ├── common.ts
│ ├── cli.ts
│ └── PrintManagerContext.ts
├── common.ts
└── generatePackageExports.ts
├── .prettierrc.cjs
├── .editorconfig
├── vite.config.ts
├── tsconfig.build.json
├── .github
└── dependabot.yml
├── tsconfig.base.json
├── .gitignore
├── .circleci
└── config.yml
├── .eslintrc.cjs
└── readme.md
/.npmignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/gallium
2 |
--------------------------------------------------------------------------------
/.huskyrc:
--------------------------------------------------------------------------------
1 | {
2 | "hooks": {
3 | "pre-commit": "lint-staged"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.lintstagedrc:
--------------------------------------------------------------------------------
1 | {
2 | "*.{ts, tsx}": [
3 | "eslint --fix"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "include": [
4 | "src",
5 | "tools"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/mocharc.json:
--------------------------------------------------------------------------------
1 | {
2 | "node-option": [
3 | "experimental-specifier-resolution=node",
4 | "loader=ts-node/esm"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/src/Typeclass/Bounded.ts:
--------------------------------------------------------------------------------
1 | import { Ord } from './Ord.js'
2 |
3 | export interface Bounded extends Ord {
4 | readonly top: A
5 | readonly bottom: A
6 | }
7 |
--------------------------------------------------------------------------------
/tools/overloads/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": "../../tsconfig.base.json",
4 | "include": [
5 | "."
6 | , "../generatePackageExports.ts" ]
7 | }
8 |
--------------------------------------------------------------------------------
/src/Json.ts:
--------------------------------------------------------------------------------
1 | export type Json = JsonPrimitive | JsonArray | JsonRecord
2 |
3 | export type JsonPrimitive = string | number | boolean | null
4 |
5 | export type JsonArray = readonly Json[]
6 |
7 | export type JsonRecord = { readonly [key: string]: Json }
8 |
--------------------------------------------------------------------------------
/.prettierrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | printWidth: 100,
3 | bracketSpacing: true,
4 | jsxBracketSameLine: false,
5 | parser: 'typescript',
6 | semi: false,
7 | singleQuote: true,
8 | tabWidth: 2,
9 | trailingComma: 'all',
10 | useTabs: false
11 | }
12 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/CommutativeBoth.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeBoth } from './AssociativeBoth.js'
2 | import { interface_ } from './common.js'
3 |
4 | export const CommutativeBoth = interface_('CommutativeBoth', [], [AssociativeBoth])
5 |
6 | export const node = CommutativeBoth
7 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Compactable.ts:
--------------------------------------------------------------------------------
1 | import { Compact } from './Compact.js'
2 | import { Separate } from './Separate.js'
3 | import { interface_ } from './common.js'
4 |
5 | export const node = interface_('Compactable', [], [Compact, Separate])
6 |
7 | export const Compactable = node
8 |
--------------------------------------------------------------------------------
/src/Typeclass/ForEach/index.ts:
--------------------------------------------------------------------------------
1 | export * from './compacted.js'
2 | export * from './composition.js'
3 | export * from './foldMap.js'
4 | export * from './ForEach.js'
5 | export * from './map.js'
6 | export * from './mapAccum.js'
7 | export * from './separated.js'
8 | export * from './sequence.js'
9 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/CommutativeEither.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeEither } from './AssociativeEither.js'
2 | import { interface_ } from './common.js'
3 |
4 | export const CommutativeEither = interface_('CommutativeEither', [], [AssociativeEither])
5 |
6 | export const node = CommutativeEither
7 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/IdentityBoth.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeBoth } from './AssociativeBoth.js'
2 | import { Top } from './Top.js'
3 | import { interface_ } from './common.js'
4 |
5 | export const IdentityBoth = interface_('IdentityBoth', [], [AssociativeBoth, Top])
6 |
7 | export const node = IdentityBoth
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | tab_width = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 | insert_final_newline = false
15 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/IdentityFlatten.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeFlatten } from './AssociativeFlatten.js'
2 | import { Top } from './Top.js'
3 | import { interface_ } from './common.js'
4 |
5 | export const IdentityFlatten = interface_('IdentityFlatten', [], [AssociativeFlatten, Top])
6 |
7 | export const node = IdentityFlatten
8 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/IdentityEither.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeEither } from './AssociativeEither.js'
2 | import { Bottom } from './Bottom.js'
3 | import { interface_ } from './common.js'
4 |
5 | export const IdentityEither = interface_('IdentityEither', [], [AssociativeEither, Bottom])
6 |
7 | export const node = IdentityEither
8 |
--------------------------------------------------------------------------------
/tools/overloads/findHKTParams.ts:
--------------------------------------------------------------------------------
1 | import { HKTParam, ParentNode, TypeParam } from './AST.js'
2 |
3 | export function findHKTParams(node: ParentNode) {
4 | return node.typeParams.filter(isHKTParam)
5 | }
6 |
7 | export function isHKTParam(param: TypeParam): param is HKTParam {
8 | return param.tag === HKTParam.tag
9 | }
10 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Identity.ts:
--------------------------------------------------------------------------------
1 | import { Interface } from '../AST.js'
2 |
3 | import { aTypeParam } from './common.js'
4 |
5 | export const node = new Interface(
6 | 'Identity',
7 | [aTypeParam],
8 | [aTypeParam.labeled('id')],
9 | [new Interface('Associative', [aTypeParam], [])],
10 | )
11 |
12 | export const Identity = node
13 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.size.ts:
--------------------------------------------------------------------------------
1 | import { FoldMap } from './FoldMap.js'
2 | import { aTypeParam, derived_, fn_, kind_, number_, placeholder } from './common.js'
3 |
4 | export const size = derived_(
5 | 'size',
6 | [FoldMap],
7 | fn_('', [placeholder, aTypeParam], [kind_([aTypeParam]).labeled()], number_),
8 | )
9 |
10 | export const node = size
11 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.isEmpty.ts:
--------------------------------------------------------------------------------
1 | import { FoldMap } from './FoldMap.js'
2 | import { aTypeParam, boolean_, derived_, fn_, kind_, placeholder } from './common.js'
3 |
4 | export const isEmpty = derived_(
5 | 'isEmpty',
6 | [FoldMap],
7 | fn_('', [placeholder, aTypeParam], [kind_([aTypeParam]).labeled()], boolean_),
8 | )
9 |
10 | export const node = isEmpty
11 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.isNonEmpty.ts:
--------------------------------------------------------------------------------
1 | import { FoldMap } from './FoldMap.js'
2 | import { aTypeParam, boolean_, derived_, fn_, kind_, placeholder } from './common.js'
3 |
4 | export const isNonEmpty = derived_(
5 | 'isNonEmpty',
6 | [FoldMap],
7 | fn_('', [placeholder, aTypeParam], [kind_([aTypeParam]).labeled()], boolean_),
8 | )
9 |
10 | export const node = isNonEmpty
11 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Top.ts:
--------------------------------------------------------------------------------
1 | import { Kind, Static } from '../AST.js'
2 |
3 | import { hkt, interface_, placeholderWithDefaults } from './common.js'
4 |
5 | const unknownType = new Static('unknown')
6 |
7 | export const Top = interface_(
8 | 'Top',
9 | [new Kind(hkt, [placeholderWithDefaults, unknownType]).labeled('top')],
10 | [],
11 | )
12 |
13 | export const node = Top
14 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Bottom.ts:
--------------------------------------------------------------------------------
1 | import { Kind, Static } from '../AST.js'
2 |
3 | import { hkt, interface_, placeholderWithDefaults } from './common.js'
4 |
5 | const neverType = new Static('never')
6 |
7 | export const Bottom = interface_(
8 | 'Bottom',
9 | [new Kind(hkt, [placeholderWithDefaults, neverType]).labeled('bottom')],
10 | [],
11 | )
12 |
13 | export const node = Bottom
14 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.addIndex.ts:
--------------------------------------------------------------------------------
1 | import { FoldMap } from './FoldMap.js'
2 | import { FoldMapWithIndex } from './FoldMapWithIndex.js'
3 | import { curriedPlaceholder_, derived_, hkt, number_ } from './common.js'
4 |
5 | export const addIndex = derived_(
6 | 'addIndex',
7 | [FoldMap],
8 | FoldMapWithIndex.toTypeClass(hkt).setParams([number_, curriedPlaceholder_(hkt)]),
9 | )
10 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Top.top.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { Top } from './Top.js'
5 | import { composed_, kindFWithDefaults_, kindGWithDefaults_ } from './common.js'
6 |
7 | export const top = composed_(
8 | 'top',
9 | [Top, Covariant],
10 | [Top],
11 | kindFWithDefaults_([kindGWithDefaults_([new Static(`unknown`)])]),
12 | )
13 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FilterMap.map.ts:
--------------------------------------------------------------------------------
1 | import { FilterMap } from './FilterMap.js'
2 | import { aTypeParam, bTypeParam, derived_, fab_, fn_, kind_, placeholder } from './common.js'
3 |
4 | export const map = derived_(
5 | 'map',
6 | [FilterMap],
7 | fn_(
8 | '',
9 | [aTypeParam, bTypeParam],
10 | [fab_],
11 | fn_('', [placeholder], [kind_([aTypeParam]).labeled()], kind_([bTypeParam])),
12 | ),
13 | )
14 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.reverse.ts:
--------------------------------------------------------------------------------
1 | import { FoldMap } from './FoldMap.js'
2 | import { ForEach } from './ForEach.js'
3 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
4 |
5 | export const reverse = derived_(
6 | 'reverse',
7 | [FoldMap, ForEach],
8 | fn_('', [placeholder, aTypeParam], [kind_([aTypeParam]).labeled()], kind_([aTypeParam])),
9 | )
10 |
11 | export const node = reverse
12 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Compact.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { aTypeParam, fnLabeled_, interface_, kind_, placeholder } from './common.js'
4 |
5 | export const node = interface_('Compact', [
6 | fnLabeled_(
7 | 'compact',
8 | [placeholder, aTypeParam],
9 | [kind_([new Static(`Maybe`)]).labeled('kind')],
10 | kind_([aTypeParam]),
11 | ),
12 | ])
13 |
14 | export const Compact = node
15 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.toArray.ts:
--------------------------------------------------------------------------------
1 | import { ArrayNode } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const toArray = derived_(
7 | 'toArray',
8 | [FoldMap],
9 | fn_('', [placeholder, aTypeParam], [kind_([aTypeParam]).labeled()], new ArrayNode(aTypeParam)),
10 | )
11 |
12 | export const node = toArray
13 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/PartitionMap.separate.ts:
--------------------------------------------------------------------------------
1 | import { KindParam, Labeled } from '../AST.js'
2 |
3 | import { PartitionMap } from './PartitionMap.js'
4 | import { Separate } from './Separate.js'
5 | import { derived_ } from './common.js'
6 |
7 | export const separate = derived_(
8 | 'separate',
9 | [PartitionMap],
10 | (Separate.properties as readonly Labeled[])[0].param,
11 | )
12 |
13 | export const node = separate
14 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Covariant.tupled.ts:
--------------------------------------------------------------------------------
1 | import { Tuple } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const node = derived_(
7 | 'tupled',
8 | [Covariant],
9 | fn_(
10 | '',
11 | [placeholder, aTypeParam],
12 | [kind_([aTypeParam]).labeled('kind')],
13 | kind_([new Tuple([aTypeParam])]),
14 | ),
15 | )
16 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Bottom.bottom.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { Bottom } from './Bottom.js'
4 | import { Covariant } from './Covariant.js'
5 | import { Top } from './Top.js'
6 | import { composed_, kindFWithDefaults_, kindGWithDefaults_ } from './common.js'
7 |
8 | export const bottom = composed_(
9 | 'bottom',
10 | [Top, Covariant],
11 | [Bottom],
12 | kindFWithDefaults_([kindGWithDefaults_([new Static(`never`)])]),
13 | )
14 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { join } from 'path'
2 |
3 | import { defineConfig } from 'vite'
4 | import tsconfigPaths from 'vite-tsconfig-paths'
5 |
6 | export default defineConfig({
7 | plugins: [
8 | tsconfigPaths({
9 | root: __dirname,
10 | }),
11 | ],
12 | build: {
13 | outDir: join(__dirname, 'build'),
14 | sourcemap: true,
15 | manifest: true,
16 | emptyOutDir: true,
17 | },
18 | server: {
19 | port: 7777,
20 | },
21 | })
22 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeFlatten.ts:
--------------------------------------------------------------------------------
1 | import { aTypeParam, fnLabeled_, interface_, kind_, placeholder } from './common.js'
2 |
3 | export const AssociativeFlatten = interface_(
4 | 'AssociativeFlatten',
5 | [
6 | fnLabeled_(
7 | 'flatten',
8 | [placeholder, aTypeParam],
9 | [kind_([kind_([aTypeParam])]).labeled('kind')],
10 | kind_([aTypeParam]),
11 | ),
12 | ],
13 | [],
14 | )
15 |
16 | export const node = AssociativeFlatten
17 |
--------------------------------------------------------------------------------
/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": "./tsconfig.base.json",
4 | "compilerOptions": {
5 | "skipLibCheck": true,
6 | "plugins": [
7 | {
8 | "transform": "@zoltu/typescript-transformer-append-js-extension/output/index.js",
9 | "after": true
10 | }
11 | ]
12 | },
13 | "include": [
14 | "src"
15 | ],
16 | "exclude": [
17 | "src/**/*.test.ts",
18 | "tools"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeEither.eventually.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeEither } from './AssociativeEither.js'
2 | import { Covariant } from './Covariant.js'
3 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
4 |
5 | export const eventually = derived_(
6 | 'eventually',
7 | [AssociativeEither, Covariant],
8 | fn_('', [placeholder, aTypeParam], [kind_([aTypeParam]).labeled('kind')], kind_([aTypeParam])),
9 | )
10 |
11 | export const node = eventually
12 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.reduceIdentity.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const reduceIdentity = derived_(
7 | 'reduceIdentity',
8 | [FoldMap],
9 | fn_(
10 | '',
11 | [aTypeParam],
12 | [new Static(`Identity`).labeled('I')],
13 | fn_('', [placeholder], [kind_([aTypeParam]).labeled()], aTypeParam),
14 | ),
15 | )
16 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeFlatten.makeAssociativeBoth.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeBoth } from './AssociativeBoth.js'
2 | import { AssociativeFlatten } from './AssociativeFlatten.js'
3 | import { Covariant } from './Covariant.js'
4 | import { derived_, hkt } from './common.js'
5 |
6 | export const makeAssociativeBoth = derived_(
7 | 'makeAssociativeBoth',
8 | [AssociativeFlatten, Covariant],
9 | AssociativeBoth.toTypeClass(hkt),
10 | )
11 |
12 | export const node = makeAssociativeBoth
13 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.foldLeft.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const foldLeft = derived_(
7 | 'foldLeft',
8 | [FoldMap],
9 | fn_(
10 | '',
11 | [aTypeParam],
12 | [new Static(`Identity<${aTypeParam.type}>`).labeled('I')],
13 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], aTypeParam),
14 | ),
15 | )
16 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Covariant.mapTo.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { aTypeParam, bTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const node = derived_(
7 | 'mapTo',
8 | [Covariant],
9 | fn_(
10 | '',
11 | [bTypeParam],
12 | [new Static('B').labeled('b')],
13 | fn_('', [placeholder, aTypeParam], [kind_([aTypeParam]).labeled('kind')], kind_([bTypeParam])),
14 | ),
15 | )
16 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.reduceAssociative.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const reduceAssociative = derived_(
7 | 'reduceAssociative',
8 | [FoldMap],
9 | fn_(
10 | '',
11 | [aTypeParam],
12 | [new Static(`Associative`).labeled('A')],
13 | fn_('', [placeholder], [kind_([aTypeParam]).labeled()], new Static(`Maybe`)),
14 | ),
15 | )
16 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.reduceCommutative.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const reduceCommutative = derived_(
7 | 'reduceCommutative',
8 | [FoldMap],
9 | fn_(
10 | '',
11 | [aTypeParam],
12 | [new Static(`Commutative`).labeled('C')],
13 | fn_('', [placeholder], [kind_([aTypeParam]).labeled()], new Static(`Maybe`)),
14 | ),
15 | )
16 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FilterMap.compact.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FilterMap } from './FilterMap.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const makeCompact = derived_(
7 | 'makeCompact',
8 | [FilterMap],
9 | fn_(
10 | '',
11 | [placeholder, aTypeParam],
12 | [kind_([new Static(`Maybe<${aTypeParam.type}>`)]).labeled('kind')],
13 | kind_([aTypeParam]),
14 | ),
15 | )
16 |
17 | export const node = makeCompact
18 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Top.makeFromValue.ts:
--------------------------------------------------------------------------------
1 | import { Covariant } from './Covariant.js'
2 | import { Top } from './Top.js'
3 | import { aTypeParam, derived_, fn_, kindWithDefaults_, placeholderWithDefaults } from './common.js'
4 |
5 | export const makeFromValue = derived_(
6 | 'makeFromValue',
7 | [Top, Covariant],
8 | fn_(
9 | '',
10 | [aTypeParam, placeholderWithDefaults],
11 | [aTypeParam.labeled('a')],
12 | kindWithDefaults_([aTypeParam]),
13 | ),
14 | )
15 |
16 | export const node = makeFromValue
17 |
--------------------------------------------------------------------------------
/src/Law/Inverse.ts:
--------------------------------------------------------------------------------
1 | import { DeepEquals, Eq } from '../Typeclass/Eq.js'
2 | import { Inverse } from '../Typeclass/Inverse.js'
3 | import { pipe } from '../function.js'
4 |
5 | import * as Arbitrary from './Arbitrary.js'
6 |
7 | export function testInverse(I: Inverse, E: Eq = DeepEquals) {
8 | return (Arb: Arbitrary.Arbitrary) =>
9 | pipe(
10 | Arb,
11 | Arbitrary.toProperty(
12 | (a) => E.equals(I.inverse(a, a), I.id) && E.equals(I.concat(I.inverse(I.id, a), a), I.id),
13 | ),
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMapWithIndex.foldMap.ts:
--------------------------------------------------------------------------------
1 | import { KindParam, Labeled } from '../AST.js'
2 |
3 | import { kTypeParam } from './CovariantWithIndex.js'
4 | import { FoldMap } from './FoldMap.js'
5 | import { FoldMapWithIndex } from './FoldMapWithIndex.js'
6 | import { derived_ } from './common.js'
7 |
8 | export const foldMapWithIndex = derived_(
9 | 'foldMap',
10 | [FoldMapWithIndex.setParams([kTypeParam])],
11 | (FoldMap.properties as readonly Labeled[])[0].param,
12 | undefined,
13 | [kTypeParam],
14 | )
15 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeBoth.zipLeft.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeBoth } from './AssociativeBoth.js'
2 | import { Covariant } from './Covariant.js'
3 | import { aTypeParam, bTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
4 |
5 | export const zipLeft = derived_(
6 | 'zipLeft',
7 | [AssociativeBoth, Covariant],
8 | fn_(
9 | '',
10 | [placeholder, bTypeParam],
11 | [kind_([bTypeParam]).labeled('second')],
12 | fn_('', [aTypeParam], [kind_([aTypeParam]).labeled('first')], kind_([aTypeParam])),
13 | ),
14 | )
15 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "npm" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "daily"
12 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeBoth.zipRight.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeBoth } from './AssociativeBoth.js'
2 | import { Covariant } from './Covariant.js'
3 | import { aTypeParam, bTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
4 |
5 | export const zipRight = derived_(
6 | 'zipRight',
7 | [AssociativeBoth, Covariant],
8 | fn_(
9 | '',
10 | [placeholder, bTypeParam],
11 | [kind_([bTypeParam]).labeled('second')],
12 | fn_('', [aTypeParam], [kind_([aTypeParam]).labeled('first')], kind_([bTypeParam])),
13 | ),
14 | )
15 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.some.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const bool = new Static(`boolean`)
7 |
8 | export const some = derived_(
9 | 'some',
10 | [FoldMap],
11 | fn_(
12 | '',
13 | [aTypeParam],
14 | [fnLabeled_('predicate', [], [aTypeParam.labeled('a')], bool)],
15 | fn_('', [placeholder], [kind_([aTypeParam]).labeled()], bool),
16 | ),
17 | )
18 |
19 | export const node = some
20 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Contravariant.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { aTypeParam, bTypeParam, fnLabeled_, fn_, interface_, kind_, placeholder } from './common.js'
4 |
5 | export const node = interface_('Contravariant', [
6 | fnLabeled_(
7 | 'contramap',
8 | [bTypeParam, aTypeParam],
9 | [new Dynamic([bTypeParam, aTypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled('f')],
10 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], kind_([bTypeParam])),
11 | ),
12 | ])
13 |
14 | export const Contravariant = node
15 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.every.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const bool = new Static(`boolean`)
7 |
8 | export const every = derived_(
9 | 'every',
10 | [FoldMap],
11 | fn_(
12 | '',
13 | [aTypeParam],
14 | [fnLabeled_('predicate', [], [aTypeParam.labeled('a')], bool)],
15 | fn_('', [placeholder], [kind_([aTypeParam]).labeled()], bool),
16 | ),
17 | )
18 |
19 | export const node = every
20 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Law/testAllHKTLaws.ts:
--------------------------------------------------------------------------------
1 | import { ObjectNode, Static } from '../../AST.js'
2 | import { curriedPlaceholder_, fn_, hkt } from '../common.js'
3 |
4 | export const testAllHKTLaws = fn_(
5 | 'testAllHKTLaws',
6 | [hkt, curriedPlaceholder_(hkt)],
7 | [
8 | new ObjectNode([
9 | new Static(`typeof import('fast-check')`).labeled('fc'),
10 | new Static(`typeof import('fast-check')`).labeled('fc'),
11 | new Static(`typeof import('fast-check')`).labeled('fc'),
12 | ]).labeled('params'),
13 | ],
14 | new Static(`void`),
15 | )
16 |
--------------------------------------------------------------------------------
/src/Law/Associative.ts:
--------------------------------------------------------------------------------
1 | import { Associative } from '../Typeclass/Associative.js'
2 | import { DeepEquals, Eq } from '../Typeclass/Eq.js'
3 | import { pipe } from '../function.js'
4 |
5 | import * as Arbitrary from './Arbitrary.js'
6 |
7 | export function testAssociativity(A: Associative, Eq: Eq = DeepEquals) {
8 | return (Arb: Arbitrary.Arbitrary) =>
9 | pipe(
10 | Arbitrary.tuple(Arb, Arb, Arb),
11 | Arbitrary.toProperty(([a, b, c]) =>
12 | Eq.equals(A.concat(a, A.concat(b, c)), A.concat(A.concat(a, b), c)),
13 | ),
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/src/Law/Commutative.ts:
--------------------------------------------------------------------------------
1 | import { Commutative } from '../Typeclass/Commutative.js'
2 | import { DeepEquals, Eq } from '../Typeclass/Eq.js'
3 | import { pipe } from '../function.js'
4 |
5 | import * as Arbitrary from './Arbitrary.js'
6 |
7 | export function testCommutativity(C: Commutative, Eq: Eq = DeepEquals) {
8 | return (Arb: Arbitrary.Arbitrary) =>
9 | pipe(
10 | Arbitrary.tuple(Arb, Arb, Arb),
11 | Arbitrary.toProperty(([a, b, c]) =>
12 | Eq.equals(C.concat(a, C.concat(b, c)), C.concat(C.concat(b, c), a)),
13 | ),
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.exists.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const bool = new Static(`boolean`)
7 |
8 | export const exists = derived_(
9 | 'exists',
10 | [FoldMap],
11 | fn_(
12 | '',
13 | [aTypeParam],
14 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], bool)],
15 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bool),
16 | ),
17 | )
18 |
19 | export const node = exists
20 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.intercalate.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const intercalate = derived_(
7 | 'intercalate',
8 | [FoldMap],
9 | fn_(
10 | '',
11 | [aTypeParam],
12 | [new Static(`Identity`).labeled('I')],
13 | fn_(
14 | '',
15 | [],
16 | [aTypeParam.labeled('a')],
17 | fn_('', [placeholder], [kind_([aTypeParam]).labeled()], aTypeParam),
18 | ),
19 | ),
20 | )
21 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Top.makeFromLazy.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { Top } from './Top.js'
5 | import { aTypeParam, derived_, fn_, kindWithDefaults_, placeholderWithDefaults } from './common.js'
6 |
7 | export const makeFromLazy = derived_(
8 | 'makeFromLazy',
9 | [Top, Covariant],
10 | fn_(
11 | '',
12 | [aTypeParam, placeholderWithDefaults],
13 | [new Static(`Lazy`).labeled('f')],
14 | kindWithDefaults_([aTypeParam]),
15 | ),
16 | )
17 |
18 | export const node = makeFromLazy
19 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Covariant.flap.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { aTypeParam, bTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const node = derived_(
7 | 'flap',
8 | [Covariant],
9 | fn_(
10 | '',
11 | [aTypeParam],
12 | [new Static('A').labeled('a')],
13 | fn_(
14 | '',
15 | [placeholder, bTypeParam],
16 | [kind_([new Dynamic([], () => `(a: A) => B`)]).labeled('kind')],
17 | kind_([bTypeParam]),
18 | ),
19 | ),
20 | )
21 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.count.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const bool = new Static(`boolean`)
7 |
8 | export const count = derived_(
9 | 'count',
10 | [FoldMap],
11 | fn_(
12 | '',
13 | [aTypeParam],
14 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], bool)],
15 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], new Static(`number`)),
16 | ),
17 | )
18 |
19 | export const node = count
20 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FilterMap.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { aTypeParam, bTypeParam, fnLabeled_, fn_, interface_, kind_, placeholder } from './common.js'
4 |
5 | export const FilterMap = interface_(
6 | 'FilterMap',
7 | [
8 | fnLabeled_(
9 | 'filterMap',
10 | [aTypeParam, bTypeParam],
11 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], new Static(`Maybe`))],
12 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], kind_([bTypeParam])),
13 | ),
14 | ],
15 | [],
16 | )
17 |
18 | export const node = FilterMap
19 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.find.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const bool = new Static(`boolean`)
7 |
8 | export const find = derived_(
9 | 'find',
10 | [FoldMap],
11 | fn_(
12 | '',
13 | [aTypeParam],
14 | [fnLabeled_('predicate', [], [aTypeParam.labeled('a')], bool)],
15 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], new Static(`Maybe`)),
16 | ),
17 | )
18 |
19 | export const node = find
20 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Compact.compact.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { Compact } from './Compact.js'
4 | import { Covariant } from './Covariant.js'
5 | import { aTypeParam, composed_, fn_, kindF_, kindG_, placeholderF, placeholderG } from './common.js'
6 |
7 | export const compact = composed_(
8 | 'compact',
9 | [Covariant],
10 | [Compact],
11 | fn_(
12 | '',
13 | [placeholderF, placeholderG, aTypeParam],
14 | [kindF_([kindG_([new Dynamic([aTypeParam], ([a]) => `Maybe<${a}>`)])]).labeled()],
15 | kindF_([kindG_([aTypeParam])]),
16 | ),
17 | )
18 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Reduce.ts:
--------------------------------------------------------------------------------
1 | import { aTypeParam, bTypeParam, fnLabeled_, fn_, interface_, kind_, placeholder } from './common.js'
2 |
3 | export const Reduce = interface_(
4 | 'Reduce',
5 | [
6 | fnLabeled_(
7 | 'reduce',
8 | [bTypeParam, aTypeParam],
9 | [
10 | bTypeParam.labeled('b'),
11 | fnLabeled_('f', [], [bTypeParam.labeled('b'), aTypeParam.labeled('a')], bTypeParam),
12 | ],
13 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bTypeParam),
14 | ),
15 | ],
16 | [],
17 | )
18 |
19 | export const node = Reduce
20 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Separate.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, Tuple } from '../AST.js'
2 |
3 | import { aTypeParam, bTypeParam, fnLabeled_, interface_, kind_, placeholder } from './common.js'
4 |
5 | export const node = interface_('Separate', [
6 | fnLabeled_(
7 | 'separate',
8 | [placeholder, aTypeParam, bTypeParam],
9 | [
10 | kind_([new Dynamic([aTypeParam, bTypeParam], ([A, B]) => `Either<${A}, ${B}>`)]).labeled(
11 | 'kind',
12 | ),
13 | ],
14 | new Tuple([kind_([aTypeParam]), kind_([bTypeParam])]),
15 | ),
16 | ])
17 |
18 | export const Separate = node
19 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Identity.fromIdentityEitherCovariant.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { IdentityEither } from './IdentityEither.js'
5 | import { aTypeParam, derived_, fn_, kindWithDefaults_, placeholder } from './common.js'
6 |
7 | export const fromIdentityEitherCovariant = derived_(
8 | 'fromIdentityEitherCovariant',
9 | [IdentityEither, Covariant],
10 | fn_(
11 | '',
12 | [placeholder, aTypeParam],
13 | [],
14 | new Dynamic([kindWithDefaults_([aTypeParam])], ([k]) => `Identity<${k}>`),
15 | ),
16 | )
17 |
--------------------------------------------------------------------------------
/src/Typeclass/Commutative.ts:
--------------------------------------------------------------------------------
1 | import * as A from './Associative.js'
2 |
3 | export interface Commutative extends A.Associative {}
4 |
5 | export const struct = A.struct as (commutatives: {
6 | readonly [K in keyof A]: Commutative
7 | }) => Commutative<{ readonly [K in keyof A]: A[K] }>
8 |
9 | export const tuple = A.tuple as (
10 | ...commutatives: { readonly [K in keyof A]: Commutative }
11 | ) => Commutative>
12 |
13 | export const concatAll = A.concatAll as (
14 | C: Commutative,
15 | ) => (startWith: A) => (as: readonly A[]) => A
16 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.reduce.ts:
--------------------------------------------------------------------------------
1 | import { FoldMap } from './FoldMap.js'
2 | import { aTypeParam, bTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
3 |
4 | export const reduce = derived_(
5 | 'reduce',
6 | [FoldMap],
7 | fn_(
8 | '',
9 | [bTypeParam, aTypeParam],
10 | [
11 | bTypeParam.labeled('seed'),
12 | fnLabeled_('f', [], [bTypeParam.labeled('b'), aTypeParam.labeled('a')], bTypeParam),
13 | ],
14 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bTypeParam),
15 | ),
16 | )
17 |
18 | export const node = reduce
19 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Covariant.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | fnLabeled_,
7 | fn_,
8 | interface_,
9 | kind_,
10 | placeholder,
11 | } from './common.js'
12 |
13 | export const node = interface_('Covariant', [
14 | fnLabeled_(
15 | 'map',
16 | [aTypeParam, bTypeParam],
17 | [new Dynamic([aTypeParam, bTypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled('f')],
18 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], kind_([bTypeParam])),
19 | ),
20 | ])
21 |
22 | export const Covariant = node
23 |
--------------------------------------------------------------------------------
/src/logical.ts:
--------------------------------------------------------------------------------
1 | import { Predicate } from './Predicate.js'
2 | import { Refinement } from './Refinement.js'
3 |
4 | export function ifElse(
5 | refinement: Refinement,
6 | ifF: (a: A1) => B,
7 | elseF: (a: A) => C,
8 | ): (value: A) => B | C
9 |
10 | export function ifElse(
11 | predicate: Predicate,
12 | ifF: (a: A) => B,
13 | elseF: (a: A) => C,
14 | ): (value: A) => B | C
15 |
16 | export function ifElse(predicate: Predicate, ifF: (a: A) => B, elseF: (a: A) => C) {
17 | return (value: A): B | C => (predicate(value) ? ifF(value) : elseF(value))
18 | }
19 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ReduceRight.ts:
--------------------------------------------------------------------------------
1 | import { aTypeParam, bTypeParam, fnLabeled_, fn_, interface_, kind_, placeholder } from './common.js'
2 |
3 | export const ReduceRight = interface_(
4 | 'ReduceRight',
5 | [
6 | fnLabeled_(
7 | 'reduceRight',
8 | [bTypeParam, aTypeParam],
9 | [
10 | bTypeParam.labeled('b'),
11 | fnLabeled_('f', [], [aTypeParam.labeled('a'), bTypeParam.labeled('b')], bTypeParam),
12 | ],
13 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bTypeParam),
14 | ),
15 | ],
16 | [],
17 | )
18 |
19 | export const node = ReduceRight
20 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ForEach.foldMap.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { ForEach } from './ForEach.js'
4 | import { aTypeParam, bTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const foldMap = derived_(
7 | 'foldMap',
8 | [ForEach],
9 | fn_(
10 | '',
11 | [bTypeParam],
12 | [new Static(`Identity`).labeled('I')],
13 | fn_(
14 | '',
15 | [aTypeParam],
16 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam)],
17 | fn_('', [placeholder], [kind_([aTypeParam]).labeled()], bTypeParam),
18 | ),
19 | ),
20 | )
21 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FilterMapWithIndex.filterMap.ts:
--------------------------------------------------------------------------------
1 | import { KindParam, Labeled, Static } from '../AST.js'
2 |
3 | import { FilterMap } from './FilterMap.js'
4 | import { FilterMapWithIndex } from './FilterMapWithIndex.js'
5 | import { curriedPlaceholder_, fn_, hkt } from './common.js'
6 |
7 | const k = new Static(`K`)
8 |
9 | export const filterMap = fn_(
10 | 'filterMap',
11 | [hkt, k, curriedPlaceholder_(hkt)],
12 | [
13 | FilterMapWithIndex.toTypeClass(hkt)
14 | .setParams([k, curriedPlaceholder_(hkt)])
15 | .labeled(),
16 | ],
17 | (FilterMap.properties as readonly Labeled[])[0].param,
18 | )
19 |
--------------------------------------------------------------------------------
/src/Law/index.ts:
--------------------------------------------------------------------------------
1 | export * from './Arbitrary.js'
2 | export * as Associative from './Associative.js'
3 | export * as AssociativeBoth from './AssociativeBoth.js'
4 | export * as AssociativeFlatten from './AssociativeFlatten.js'
5 | export * as Commutative from './Commutative.js'
6 | export * as Contravariant from './Contravariant.js'
7 | export * as Covariant from './Covariant.js'
8 | export * as Eq from './Eq.js'
9 | export * as Identity from './Identity.js'
10 | export * as IdentityBoth from './IdentityBoth.js'
11 | export * as IdentityFlatten from './IdentityFlatten.js'
12 | export * as Inverse from './Inverse.js'
13 | export * as Ord from './Ord.js'
14 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeFlatten.flatMap.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeFlatten } from './AssociativeFlatten.js'
2 | import { Covariant } from './Covariant.js'
3 | import { aTypeParam, bTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
4 |
5 | export const flatMap = derived_(
6 | 'flatMap',
7 | [AssociativeFlatten, Covariant],
8 | fn_(
9 | '',
10 | [aTypeParam, placeholder, bTypeParam],
11 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], kind_([bTypeParam]))],
12 | fn_('', [], [kind_([aTypeParam]).labeled('kind')], kind_([bTypeParam])),
13 | ),
14 | )
15 |
16 | export const node = flatMap
17 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Divariant.map.ts:
--------------------------------------------------------------------------------
1 | import { Divariant } from './Divariant.js'
2 | import {
3 | aTypeParam,
4 | bTypeParam,
5 | cTypeParam,
6 | derived_,
7 | fnLabeled_,
8 | fn_,
9 | kind_,
10 | placeholder,
11 | } from './common.js'
12 |
13 | export const map = derived_(
14 | 'map',
15 | [Divariant],
16 | fn_(
17 | '',
18 | [bTypeParam, cTypeParam],
19 | [fnLabeled_('f', [], [bTypeParam.labeled('b')], cTypeParam)],
20 | fn_(
21 | '',
22 | [placeholder, aTypeParam],
23 | [kind_([aTypeParam, bTypeParam]).labeled()],
24 | kind_([aTypeParam, cTypeParam]),
25 | ),
26 | ),
27 | )
28 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.contains.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const bool = new Static(`boolean`)
7 |
8 | export const contains = derived_(
9 | 'contains',
10 | [FoldMap],
11 | fn_(
12 | '',
13 | [aTypeParam],
14 | [new Static(`Eq`).labeled('E')],
15 | fn_(
16 | '',
17 | [],
18 | [aTypeParam.labeled('a')],
19 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bool),
20 | ),
21 | ),
22 | )
23 |
24 | export const node = contains
25 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Trivariant.map.ts:
--------------------------------------------------------------------------------
1 | import { Trivariant } from './Trivariant.js'
2 | import {
3 | aTypeParam,
4 | bTypeParam,
5 | cTypeParam,
6 | dTypeParam,
7 | derived_,
8 | fab_,
9 | fn_,
10 | kind_,
11 | placeholder,
12 | } from './common.js'
13 |
14 | export const map = derived_(
15 | 'map',
16 | [Trivariant],
17 | fn_(
18 | '',
19 | [aTypeParam, bTypeParam],
20 | [fab_],
21 | fn_(
22 | '',
23 | [placeholder, cTypeParam, dTypeParam],
24 | [kind_([cTypeParam, dTypeParam, aTypeParam]).labeled()],
25 | kind_([cTypeParam, dTypeParam, bTypeParam]),
26 | ),
27 | ),
28 | )
29 |
--------------------------------------------------------------------------------
/src/string.test.ts:
--------------------------------------------------------------------------------
1 | import * as fc from 'fast-check'
2 | import { describe } from 'vitest'
3 |
4 | import * as L from './Law/index.js'
5 | import { testAllDataLaws } from './Law/internal-test-all-laws.js'
6 | import * as S from './string.js'
7 |
8 | describe(import.meta.url, () => {
9 | testAllDataLaws({
10 | name: 'String Instances',
11 | fc,
12 | Arbitrary: L.string(),
13 | Eq: {
14 | string: S.Eq,
15 | },
16 | Ord: {
17 | string: S.Ord,
18 | },
19 | Associative: {
20 | string: [S.Associative, S.Eq],
21 | },
22 | Identity: {
23 | string: [S.Identity, S.Eq],
24 | },
25 | })
26 | })
27 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ReduceWithIndex.reduce.ts:
--------------------------------------------------------------------------------
1 | import { KindParam, Labeled, Static } from '../AST.js'
2 |
3 | import { Reduce } from './Reduce.js'
4 | import { ReduceWithIndex } from './ReduceWithIndex.js'
5 | import { curriedPlaceholder_, fn_, hkt } from './common.js'
6 |
7 | const k = new Static(`K`)
8 |
9 | export const reduce = fn_(
10 | 'reduce',
11 | [hkt, k, curriedPlaceholder_(hkt)],
12 | [
13 | ReduceWithIndex.toTypeClass(hkt)
14 | .setParams([k, curriedPlaceholder_(hkt)])
15 | .labeled('RI'),
16 | ],
17 | (Reduce.properties as readonly Labeled[])[0].param,
18 | )
19 |
20 | export const node = reduce
21 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeCompose.ts:
--------------------------------------------------------------------------------
1 | import {
2 | aTypeParam,
3 | bTypeParam,
4 | cTypeParam,
5 | fnLabeled_,
6 | fn_,
7 | interface_,
8 | kind_,
9 | placeholder,
10 | } from './common.js'
11 |
12 | export const node = interface_('AssociativeCompose', [
13 | fnLabeled_(
14 | 'compose',
15 | [placeholder, bTypeParam, cTypeParam],
16 | [kind_([bTypeParam, cTypeParam]).labeled('second')],
17 | fn_(
18 | '',
19 | [aTypeParam],
20 | [kind_([aTypeParam, bTypeParam]).labeled('first')],
21 | kind_([aTypeParam, cTypeParam]),
22 | ),
23 | ),
24 | ])
25 |
26 | export const AssociativeCompose = node
27 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Bicovariant.map.ts:
--------------------------------------------------------------------------------
1 | import { Bicovariant } from './Bicovariant.js'
2 | import {
3 | aTypeParam,
4 | bTypeParam,
5 | cTypeParam,
6 | derived_,
7 | fnLabeled_,
8 | fn_,
9 | kind_,
10 | placeholder,
11 | } from './common.js'
12 |
13 | export const node = derived_(
14 | 'map',
15 | [Bicovariant],
16 | fn_(
17 | '',
18 | [aTypeParam, bTypeParam],
19 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam)],
20 | fn_(
21 | '',
22 | [placeholder, cTypeParam],
23 | [kind_([cTypeParam, aTypeParam]).labeled('kind')],
24 | kind_([cTypeParam, bTypeParam]),
25 | ),
26 | ),
27 | )
28 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.groupBy.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import { aTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const k = new Static(`K`)
7 |
8 | export const groupBy = derived_(
9 | 'groupBy',
10 | [FoldMap],
11 | fn_(
12 | '',
13 | [k, aTypeParam],
14 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], k)],
15 | fn_(
16 | '',
17 | [placeholder],
18 | [kind_([aTypeParam]).labeled()],
19 | new Static(`ReadonlyMap>`),
20 | ),
21 | ),
22 | )
23 |
24 | export const node = groupBy
25 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeBoth.ts:
--------------------------------------------------------------------------------
1 | import { Tuple } from '../AST.js'
2 |
3 | import { aTypeParam, bTypeParam, fnLabeled_, fn_, interface_, kind_, placeholder } from './common.js'
4 |
5 | export const AssociativeBoth = interface_(
6 | 'AssociativeBoth',
7 | [
8 | fnLabeled_(
9 | 'both',
10 | [placeholder, bTypeParam],
11 | [kind_([bTypeParam]).labeled('second')],
12 | fn_(
13 | '',
14 | [aTypeParam],
15 | [kind_([aTypeParam]).labeled('first')],
16 | kind_([new Tuple([aTypeParam, bTypeParam])]),
17 | ),
18 | ),
19 | ],
20 | [],
21 | )
22 |
23 | export const node = AssociativeBoth
24 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Divariant.contramap.ts:
--------------------------------------------------------------------------------
1 | import { Divariant } from './Divariant.js'
2 | import {
3 | aTypeParam,
4 | bTypeParam,
5 | cTypeParam,
6 | derived_,
7 | fnLabeled_,
8 | fn_,
9 | kind_,
10 | placeholder,
11 | } from './common.js'
12 |
13 | export const contramap = derived_(
14 | 'contramap',
15 | [Divariant],
16 | fn_(
17 | '',
18 | [bTypeParam, cTypeParam],
19 | [fnLabeled_('f', [], [bTypeParam.labeled('b')], cTypeParam)],
20 | fn_(
21 | '',
22 | [placeholder, aTypeParam],
23 | [kind_([cTypeParam, aTypeParam]).labeled()],
24 | kind_([bTypeParam, aTypeParam]),
25 | ),
26 | ),
27 | )
28 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMapWithIndex.toMap.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMapWithIndex } from './FoldMapWithIndex.js'
4 | import { aTypeParam, curriedPlaceholder_, fn_, hkt, kind_, placeholder } from './common.js'
5 |
6 | const k = new Static(`K`)
7 |
8 | export const toMap = fn_(
9 | 'toMap',
10 | [hkt, k, curriedPlaceholder_(hkt)],
11 | [
12 | FoldMapWithIndex.toTypeClass(hkt)
13 | .setParams([k, curriedPlaceholder_(hkt)])
14 | .labeled(),
15 | ],
16 | fn_(
17 | '',
18 | [placeholder, aTypeParam],
19 | [kind_([aTypeParam]).labeled()],
20 | new Static(`ReadonlyMap`),
21 | ),
22 | )
23 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Bicovariant.mapLeft.ts:
--------------------------------------------------------------------------------
1 | import { Bicovariant } from './Bicovariant.js'
2 | import {
3 | aTypeParam,
4 | bTypeParam,
5 | cTypeParam,
6 | derived_,
7 | fnLabeled_,
8 | fn_,
9 | kind_,
10 | placeholder,
11 | } from './common.js'
12 |
13 | export const node = derived_(
14 | 'mapLeft',
15 | [Bicovariant],
16 | fn_(
17 | '',
18 | [aTypeParam, bTypeParam],
19 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam)],
20 | fn_(
21 | '',
22 | [placeholder, cTypeParam],
23 | [kind_([aTypeParam, cTypeParam]).labeled('kind')],
24 | kind_([bTypeParam, cTypeParam]),
25 | ),
26 | ),
27 | )
28 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Covariant.bindTo.ts:
--------------------------------------------------------------------------------
1 | import { ObjectNode, Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | export const nameTypeParam = new Static('N extends string')
7 |
8 | export const node = derived_(
9 | 'bindTo',
10 | [Covariant],
11 | fn_(
12 | '',
13 | [nameTypeParam],
14 | [nameTypeParam.labeled('name')],
15 | fn_(
16 | '',
17 | [placeholder, aTypeParam],
18 | [kind_([aTypeParam]).labeled('kind')],
19 | kind_([new ObjectNode([new Static('A').labeled(`[K in N]`)])]),
20 | ),
21 | ),
22 | )
23 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { aTypeParam, bTypeParam, fnLabeled_, fn_, interface_, kind_, placeholder } from './common.js'
4 |
5 | export const FoldMap = interface_(
6 | 'FoldMap',
7 | [
8 | fnLabeled_(
9 | 'foldMap',
10 | [bTypeParam],
11 | [new Static(`Identity`).labeled('ID')],
12 | fn_(
13 | '',
14 | [aTypeParam],
15 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam)],
16 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bTypeParam),
17 | ),
18 | ),
19 | ],
20 | [],
21 | )
22 |
23 | export const node = FoldMap
24 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/NaturalTransformation.ts:
--------------------------------------------------------------------------------
1 | import { Interface } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | curriedPlaceholder_,
6 | fnLabeled_,
7 | hktF,
8 | hktG,
9 | kindF_,
10 | kindG_,
11 | placeholderF,
12 | placeholderG,
13 | } from './common.js'
14 |
15 | export const NaturalTransformation = new Interface(
16 | 'NaturalTransformation',
17 | [hktF, curriedPlaceholder_(hktF), hktG, curriedPlaceholder_(hktG)],
18 | [
19 | fnLabeled_(
20 | 'naturalTransformation',
21 | [placeholderF, aTypeParam, placeholderG],
22 | [kindF_([aTypeParam]).labeled()],
23 | kindG_([aTypeParam]),
24 | ),
25 | ],
26 | )
27 |
--------------------------------------------------------------------------------
/src/Typeclass/Inverse.ts:
--------------------------------------------------------------------------------
1 | import { Identity } from './Identity.js'
2 |
3 | export interface Inverse extends Identity {
4 | readonly inverse: (a: A, b: A) => A
5 | }
6 |
7 | export function multiply(I: Inverse) {
8 | return (a: A, amount: number) => {
9 | if (amount === 0) {
10 | return I.id
11 | }
12 |
13 | let i = amount
14 | let r = I.id
15 |
16 | const multiply_ = amount > 0 ? () => (r = I.concat(r, a)) : () => (r = I.inverse(r, a))
17 | const updateIndex = amount > 0 ? () => (i -= 1) : () => (i += 1)
18 |
19 | while (i !== 0) {
20 | multiply_()
21 | updateIndex()
22 | }
23 |
24 | return r
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Invariant.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { aTypeParam, bTypeParam, fnLabeled_, fn_, interface_, kind_, placeholder } from './common.js'
4 |
5 | export const node = interface_('Invariant', [
6 | fnLabeled_(
7 | 'imap',
8 | [aTypeParam, bTypeParam],
9 | [
10 | new Dynamic([aTypeParam, bTypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled('f'),
11 | new Dynamic([aTypeParam, bTypeParam] as const, ([a, b]) => `Unary<${b}, ${a}>`).labeled('g'),
12 | ],
13 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], kind_([bTypeParam])),
14 | ),
15 | ])
16 |
17 | export const Invariant = node
18 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.reduceRight.ts:
--------------------------------------------------------------------------------
1 | import { FoldMap } from './FoldMap.js'
2 | import { ForEach } from './ForEach.js'
3 | import { aTypeParam, bTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
4 |
5 | export const reduceRight = derived_(
6 | 'reduceRight',
7 | [FoldMap, ForEach],
8 | fn_(
9 | 'reduceRight',
10 | [bTypeParam, aTypeParam],
11 | [
12 | bTypeParam.labeled('b'),
13 | fnLabeled_('f', [], [aTypeParam.labeled('a'), bTypeParam.labeled('b')], bTypeParam),
14 | ],
15 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bTypeParam),
16 | ),
17 | )
18 |
19 | export const node = reduceRight
20 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Reduce.reduce.ts:
--------------------------------------------------------------------------------
1 | import { Reduce } from './Reduce.js'
2 | import {
3 | aTypeParam,
4 | bTypeParam,
5 | composed_,
6 | fnLabeled_,
7 | fn_,
8 | kindF_,
9 | kindG_,
10 | placeholderF,
11 | placeholderG,
12 | } from './common.js'
13 |
14 | export const reduce = composed_(
15 | 'reduce',
16 | [Reduce],
17 | [Reduce],
18 | fn_(
19 | '',
20 | [bTypeParam, aTypeParam],
21 | [
22 | bTypeParam.labeled('seed'),
23 | fnLabeled_('f', [], [bTypeParam.labeled('b'), aTypeParam.labeled('a')], bTypeParam),
24 | ],
25 | fn_('', [placeholderF, placeholderG], [kindF_([kindG_([aTypeParam])]).labeled()], bTypeParam),
26 | ),
27 | )
28 |
--------------------------------------------------------------------------------
/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": true,
4 | "declarationMap": true,
5 | "downlevelIteration": true,
6 | "esModuleInterop": true,
7 | "importHelpers": true,
8 | "module": "ES2015",
9 | "moduleResolution": "NodeNext",
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noUnusedLocals": true,
13 | "noUnusedParameters": true,
14 | "strict": true,
15 | "strictFunctionTypes": true,
16 | "strictNullChecks": true,
17 | "strictPropertyInitialization": true,
18 | "sourceMap": true,
19 | "target": "es2019",
20 | "lib": [
21 | "DOM",
22 | "es2019"
23 | ]
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeFlatten.flatten.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeFlatten } from './AssociativeFlatten.js'
2 | import { Covariant } from './Covariant.js'
3 | import { ForEach } from './ForEach.js'
4 | import { IdentityBoth } from './IdentityBoth.js'
5 | import { aTypeParam, composed_, fn_, kindF_, kindG_, placeholderF, placeholderG } from './common.js'
6 |
7 | export const flatten = composed_(
8 | 'flatten',
9 | [IdentityBoth, AssociativeFlatten, Covariant],
10 | [AssociativeFlatten, ForEach],
11 | fn_(
12 | '',
13 | [placeholderF, placeholderG, aTypeParam],
14 | [kindF_([kindG_([kindF_([kindG_([aTypeParam])])])]).labeled()],
15 | kindF_([kindG_([aTypeParam])]),
16 | ),
17 | )
18 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.foldMap.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { FoldMap } from './FoldMap.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | composed_,
8 | fab_,
9 | fn_,
10 | kindF_,
11 | kindG_,
12 | placeholderF,
13 | placeholderG,
14 | } from './common.js'
15 |
16 | export const foldMap = composed_(
17 | 'foldMap',
18 | [FoldMap],
19 | [FoldMap],
20 | fn_(
21 | '',
22 | [bTypeParam],
23 | [new Static(`Identity`).labeled('I')],
24 | fn_(
25 | '',
26 | [aTypeParam],
27 | [fab_],
28 | fn_('', [placeholderF, placeholderG], [kindF_([kindG_([aTypeParam])]).labeled()], bTypeParam),
29 | ),
30 | ),
31 | )
32 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ReduceRightWithIndex.reduceRight.ts:
--------------------------------------------------------------------------------
1 | import { KindParam, Labeled, Static } from '../AST.js'
2 |
3 | import { ReduceRight } from './ReduceRight.js'
4 | import { ReduceRightWithIndex } from './ReduceRightWithIndex.js'
5 | import { curriedPlaceholder_, fn_, hkt } from './common.js'
6 |
7 | const k = new Static(`K`)
8 |
9 | export const reduceRight = fn_(
10 | 'reduceRight',
11 | [hkt, k, curriedPlaceholder_(hkt)],
12 | [
13 | ReduceRightWithIndex.toTypeClass(hkt)
14 | .setParams([k, curriedPlaceholder_(hkt)])
15 | .labeled('RRI'),
16 | ],
17 | (ReduceRight.properties as readonly Labeled[])[0].param,
18 | )
19 |
20 | export const node = reduceRight
21 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeEither.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { aTypeParam, bTypeParam, fnLabeled_, fn_, interface_, kind_, placeholder } from './common.js'
4 |
5 | export const AssociativeEither = interface_(
6 | 'AssociativeEither',
7 | [
8 | fnLabeled_(
9 | 'either',
10 | [placeholder, bTypeParam],
11 | [kind_([bTypeParam]).labeled('second')],
12 | fn_(
13 | '',
14 | [aTypeParam],
15 | [kind_([aTypeParam]).labeled('first')],
16 | kind_([new Dynamic([aTypeParam, bTypeParam], ([a, b]) => `Either<${a}, ${b}>`)]),
17 | ),
18 | ),
19 | ],
20 | [],
21 | )
22 |
23 | export const node = AssociativeEither
24 |
--------------------------------------------------------------------------------
/src/boolean.test.ts:
--------------------------------------------------------------------------------
1 | import * as fc from 'fast-check'
2 | import { describe } from 'vitest'
3 |
4 | import * as L from './Law/index.js'
5 | import { testAllDataLaws } from './Law/internal-test-all-laws.js'
6 | import * as B from './boolean.js'
7 |
8 | describe(import.meta.url, () => {
9 | testAllDataLaws({
10 | name: 'Boolean Instances',
11 | fc,
12 | Arbitrary: L.boolean,
13 | Eq: {
14 | boolean: B.Eq,
15 | },
16 | Ord: {
17 | boolean: B.Ord,
18 | },
19 | Associative: {
20 | All: [B.AssociativeAll, B.Eq],
21 | Any: [B.AssociativeAny, B.Eq],
22 | },
23 | Identity: {
24 | All: [B.All, B.Eq],
25 | Any: [B.Any, B.Eq],
26 | },
27 | })
28 | })
29 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ReduceRight.reduceRight.ts:
--------------------------------------------------------------------------------
1 | import { ReduceRight } from './ReduceRight.js'
2 | import {
3 | aTypeParam,
4 | bTypeParam,
5 | composed_,
6 | fnLabeled_,
7 | fn_,
8 | kindF_,
9 | kindG_,
10 | placeholderF,
11 | placeholderG,
12 | } from './common.js'
13 |
14 | export const reduceRight = composed_(
15 | 'reduceRight',
16 | [ReduceRight],
17 | [ReduceRight],
18 | fn_(
19 | '',
20 | [bTypeParam, aTypeParam],
21 | [
22 | bTypeParam.labeled('b'),
23 | fnLabeled_('f', [], [aTypeParam.labeled('a'), bTypeParam.labeled('b')], bTypeParam),
24 | ],
25 | fn_('', [placeholderF, placeholderG], [kindF_([kindG_([aTypeParam])]).labeled()], bTypeParam),
26 | ),
27 | )
28 |
--------------------------------------------------------------------------------
/src/Typeclass/Concat.ts:
--------------------------------------------------------------------------------
1 | import { Lazy, identity, second } from '../function.js'
2 |
3 | // Concat represents a concatenation that does NOT have any associated laws.
4 | export interface Concat {
5 | readonly concat: (first: A, second: A) => A
6 | }
7 |
8 | export const First: Concat = { concat: identity }
9 | export const Second: Concat = { concat: second }
10 |
11 | export const concatAll =
12 | (M: Concat) =>
13 | (startWith: A) =>
14 | (as: ReadonlyArray): A =>
15 | as.reduce(M.concat, startWith)
16 |
17 | export const reverse = (M: Concat): Concat => ({
18 | concat: (f, s) => M.concat(s, f),
19 | })
20 |
21 | export const fromLazy = (f: Lazy): Concat => ({
22 | concat: f,
23 | })
24 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Contravariant.contramap.ts:
--------------------------------------------------------------------------------
1 | import { Contravariant } from './Contravariant.js'
2 | import {
3 | aTypeParam,
4 | bTypeParam,
5 | composed_,
6 | fnLabeled_,
7 | fn_,
8 | kindF_,
9 | kindG_,
10 | placeholderF,
11 | placeholderG,
12 | } from './common.js'
13 |
14 | export const contramap = composed_(
15 | 'contramap',
16 | [Contravariant],
17 | [Contravariant],
18 | fn_(
19 | '',
20 | [bTypeParam, aTypeParam],
21 | [fnLabeled_('f', [], [bTypeParam.labeled('b')], aTypeParam)],
22 | fn_(
23 | '',
24 | [placeholderF, placeholderG, aTypeParam],
25 | [kindF_([kindG_([aTypeParam])]).labeled()],
26 | kindF_([kindG_([bTypeParam])]),
27 | ),
28 | ),
29 | )
30 |
--------------------------------------------------------------------------------
/src/Progress.test.ts:
--------------------------------------------------------------------------------
1 | import * as fc from 'fast-check'
2 | import { describe } from 'vitest'
3 |
4 | import * as L from './Law/index.js'
5 | import { testAllDataLaws } from './Law/internal-test-all-laws.js'
6 | import * as P from './Progress.js'
7 |
8 | describe(import.meta.url, () => {
9 | testAllDataLaws({
10 | name: `Progress Instances`,
11 | fc,
12 | Arbitrary: L.Progress,
13 | Associative: {
14 | Progress: [P.Associative, P.Eq],
15 | },
16 | Commutative: {
17 | Progress: [P.Commutative, P.Eq],
18 | },
19 | Identity: {
20 | Progress: [P.Identity, P.Eq],
21 | },
22 | Eq: {
23 | Progress: P.Eq,
24 | },
25 | Ord: {
26 | Progress: P.Ord,
27 | },
28 | })
29 | })
30 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeEither.orElse.ts:
--------------------------------------------------------------------------------
1 | import { UnionNode } from '../AST.js'
2 |
3 | import { AssociativeEither } from './AssociativeEither.js'
4 | import { Covariant } from './Covariant.js'
5 | import { aTypeParam, bTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
6 |
7 | export const orElse = derived_(
8 | 'orElse',
9 | [AssociativeEither, Covariant],
10 | fn_(
11 | '',
12 | [placeholder, bTypeParam],
13 | [fnLabeled_('f', [], [], kind_([bTypeParam]))],
14 | fn_(
15 | '',
16 | [aTypeParam],
17 | [kind_([aTypeParam]).labeled('kind')],
18 | kind_([new UnionNode(aTypeParam, bTypeParam)]),
19 | ),
20 | ),
21 | )
22 |
23 | export const node = orElse
24 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Covariant.map.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | composed_,
8 | fn_,
9 | kindF_,
10 | kindG_,
11 | placeholderF,
12 | placeholderG,
13 | } from './common.js'
14 |
15 | export const map = composed_(
16 | 'map',
17 | [Covariant],
18 | [Covariant],
19 | fn_(
20 | '',
21 | [aTypeParam, bTypeParam],
22 | [new Dynamic([aTypeParam, bTypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled('f')],
23 | fn_(
24 | '',
25 | [placeholderF, placeholderG],
26 | [kindF_([kindG_([aTypeParam])]).labeled()],
27 | kindF_([kindG_([bTypeParam])]),
28 | ),
29 | ),
30 | )
31 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Invariant.imap.ts:
--------------------------------------------------------------------------------
1 | import { Covariant } from './Covariant.js'
2 | import { Invariant } from './Invariant.js'
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | composed_,
7 | fab_,
8 | fnLabeled_,
9 | fn_,
10 | kindF_,
11 | kindG_,
12 | placeholderF,
13 | placeholderG,
14 | } from './common.js'
15 |
16 | export const imap = composed_(
17 | 'imap',
18 | [Covariant],
19 | [Invariant],
20 | fn_(
21 | '',
22 | [aTypeParam, bTypeParam],
23 | [fab_, fnLabeled_('g', [], [bTypeParam.labeled('b')], aTypeParam)],
24 | fn_(
25 | '',
26 | [placeholderF, placeholderG],
27 | [kindF_([kindG_([aTypeParam])]).labeled()],
28 | kindF_([kindG_([bTypeParam])]),
29 | ),
30 | ),
31 | )
32 |
--------------------------------------------------------------------------------
/src/Id.ts:
--------------------------------------------------------------------------------
1 | import { HKT, Params } from './HKT.js'
2 | import { AssociativeBoth1 } from './Typeclass/AssociativeBoth.js'
3 | import { Covariant1 } from './Typeclass/Covariant.js'
4 | import { IdentityBoth1 } from './Typeclass/IdentityBoth.js'
5 | import { Top1 } from './Typeclass/Top.js'
6 |
7 | export type Id = A
8 |
9 | export interface IdHKT extends HKT {
10 | readonly type: Id
11 | }
12 |
13 | export const AssociativeBoth: AssociativeBoth1 = {
14 | both: (s) => (f) => [f, s],
15 | }
16 |
17 | export const Covariant: Covariant1 = {
18 | map: (f) => (a) => f(a),
19 | }
20 |
21 | export const Top: Top1 = {
22 | top: [],
23 | }
24 |
25 | export const IdentityBoth: IdentityBoth1 = {
26 | ...AssociativeBoth,
27 | ...Top,
28 | }
29 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Contravariant.contramapC.ts:
--------------------------------------------------------------------------------
1 | import { Contravariant } from './Contravariant.js'
2 | import { Covariant } from './Covariant.js'
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | composed_,
7 | fnLabeled_,
8 | fn_,
9 | kindF_,
10 | kindG_,
11 | placeholderF,
12 | placeholderG,
13 | } from './common.js'
14 |
15 | export const contramap = composed_(
16 | 'contramapC',
17 | [Covariant],
18 | [Contravariant],
19 | fn_(
20 | '',
21 | [bTypeParam, aTypeParam],
22 | [fnLabeled_('f', [], [bTypeParam.labeled('b')], aTypeParam)],
23 | fn_(
24 | '',
25 | [placeholderF, placeholderG, aTypeParam],
26 | [kindF_([kindG_([aTypeParam])]).labeled()],
27 | kindF_([kindG_([bTypeParam])]),
28 | ),
29 | ),
30 | )
31 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ForEach.map.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { ForEach } from './ForEach.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | curriedPlaceholder_,
8 | fnLabeled_,
9 | fn_,
10 | hkt,
11 | kind_,
12 | placeholder,
13 | } from './common.js'
14 |
15 | export const map = fn_(
16 | 'map',
17 | [hkt, curriedPlaceholder_(hkt)],
18 | [
19 | new Dynamic(
20 | [ForEach.toTypeClass(hkt).setParams([curriedPlaceholder_(hkt)])],
21 | (f) => `${f}['forEach']`,
22 | ).labeled('forEach'),
23 | ],
24 | fn_(
25 | '',
26 | [aTypeParam, bTypeParam],
27 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam)],
28 | fn_('', [placeholder], [kind_([aTypeParam]).labeled()], kind_([bTypeParam])),
29 | ),
30 | )
31 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Trivariant.contramap.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { Trivariant } from './Trivariant.js'
4 | import { aTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const eTypeParam = new Static(`E`)
7 | const r1TypeParam = new Static(`R1`)
8 | const r2TypeParam = new Static(`R2`)
9 |
10 | export const contramap = derived_(
11 | 'contramap',
12 | [Trivariant],
13 | fn_(
14 | '',
15 | [r1TypeParam, r2TypeParam],
16 | [fnLabeled_('f', [], [r1TypeParam.labeled('r1')], r2TypeParam)],
17 | fn_(
18 | '',
19 | [placeholder, eTypeParam, aTypeParam],
20 | [kind_([r2TypeParam, eTypeParam, aTypeParam]).labeled()],
21 | kind_([r1TypeParam, eTypeParam, aTypeParam]),
22 | ),
23 | ),
24 | )
25 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeEither.tuple.ts:
--------------------------------------------------------------------------------
1 | import { ArrayNode, Dynamic, Kind, Static } from '../AST.js'
2 |
3 | import { AssociativeEither } from './AssociativeEither.js'
4 | import { Covariant } from './Covariant.js'
5 | import { derived_, fn_, hkt, kindWithDefaults_, placeholder } from './common.js'
6 |
7 | export const tuple = derived_(
8 | 'tuple',
9 | [AssociativeEither, Covariant],
10 | fn_(
11 | '',
12 | [new ArrayNode(kindWithDefaults_([new Static('any')])).nonEmpty().labeled('AS')],
13 | [new Static(`AS`).labeled('...values')],
14 | new Kind(hkt, [
15 | placeholder.extract(`AS[number]`),
16 | new Dynamic(
17 | [hkt],
18 | ([hkt]) => `ParamOf<${hkt.split('extends')[0].trim()}, AS[number], Params.A>`,
19 | ),
20 | ]),
21 | ),
22 | )
23 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/IdentityBoth.tuple.ts:
--------------------------------------------------------------------------------
1 | import { ArrayNode, Dynamic, Kind, Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { IdentityBoth } from './IdentityBoth.js'
5 | import { derived_, fn_, hkt, kindWithDefaults_, placeholder } from './common.js'
6 |
7 | export const tuple = derived_(
8 | 'tuple',
9 | [IdentityBoth, Covariant],
10 | fn_(
11 | '',
12 | [new ArrayNode(kindWithDefaults_([new Static('any')])).labeled('AS')],
13 | [new Static(`AS`).labeled('...values')],
14 | new Kind(hkt, [
15 | placeholder.extract(`AS[number]`),
16 | new Dynamic(
17 | [hkt],
18 | ([hkt]) => `{ readonly [K in keyof AS]: ParamOf<${hkt}, AS[K], Params.A> }`,
19 | ),
20 | ]),
21 | ),
22 | )
23 |
24 | export const node = tuple
25 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeBoth.both.ts:
--------------------------------------------------------------------------------
1 | import { Tuple } from '../AST.js'
2 |
3 | import { AssociativeBoth } from './AssociativeBoth.js'
4 | import { Covariant } from './Covariant.js'
5 | import {
6 | aTypeParam,
7 | bTypeParam,
8 | composed_,
9 | fn_,
10 | kindF_,
11 | kindG_,
12 | placeholderF,
13 | placeholderG,
14 | } from './common.js'
15 |
16 | export const both = composed_(
17 | 'both',
18 | [AssociativeBoth, Covariant],
19 | [AssociativeBoth],
20 | fn_(
21 | '',
22 | [placeholderF, placeholderG, bTypeParam],
23 | [kindF_([kindG_([bTypeParam])]).labeled('second')],
24 | fn_(
25 | '',
26 | [aTypeParam],
27 | [kindF_([kindG_([aTypeParam])]).labeled('first')],
28 | kindF_([kindG_([new Tuple([aTypeParam, bTypeParam])])]),
29 | ),
30 | ),
31 | )
32 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FilterMap.filterMap.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { FilterMap } from './FilterMap.js'
5 | import {
6 | aTypeParam,
7 | bTypeParam,
8 | composed_,
9 | fnLabeled_,
10 | fn_,
11 | kindF_,
12 | kindG_,
13 | placeholderF,
14 | placeholderG,
15 | } from './common.js'
16 |
17 | export const filterMap = composed_(
18 | 'filterMap',
19 | [Covariant],
20 | [FilterMap],
21 | fn_(
22 | 'filterMap',
23 | [aTypeParam, bTypeParam],
24 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], new Static(`Maybe`))],
25 | fn_(
26 | '',
27 | [placeholderF, placeholderG],
28 | [kindF_([kindG_([aTypeParam])]).labeled('kind')],
29 | kindF_([kindG_([bTypeParam])]),
30 | ),
31 | ),
32 | )
33 |
--------------------------------------------------------------------------------
/src/Match.ts:
--------------------------------------------------------------------------------
1 | import * as M from './Maybe.js'
2 | import { flow, pipe } from './function.js'
3 |
4 | export interface Match {
5 | (a: A): M.Maybe
6 | }
7 |
8 | export const map =
9 | (f: (a: A) => B) =>
10 | (match: Match): Match =>
11 | flow(match, M.map(f))
12 |
13 | export const mapMaybe =
14 | (f: (a: A) => M.Maybe) =>
15 | (match: Match): Match =>
16 | flow(match, M.flatMap(f))
17 |
18 | export const flatMap =
19 | (f: (a: A) => Match) =>
20 | (match: Match): Match =>
21 | (i) =>
22 | pipe(
23 | i,
24 | match,
25 | M.flatMap((a) => f(a)(i)),
26 | )
27 |
28 | export const getOrElse =
29 | (orElse: () => B) =>
30 | (match: Match) =>
31 | flow(match, M.getOrElse(orElse))
32 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Trivariant.bimap.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { Trivariant } from './Trivariant.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | cTypeParam,
8 | dTypeParam,
9 | derived_,
10 | fab_,
11 | fnLabeled_,
12 | fn_,
13 | kind_,
14 | placeholder,
15 | } from './common.js'
16 |
17 | const rTypeParam = new Static(`R`)
18 |
19 | export const bimap = derived_(
20 | 'bimap',
21 | [Trivariant],
22 | fn_(
23 | '',
24 | [aTypeParam, bTypeParam, cTypeParam, dTypeParam],
25 | [fab_, fnLabeled_('g', [], [cTypeParam.labeled('c')], dTypeParam)],
26 | fn_(
27 | '',
28 | [placeholder, rTypeParam],
29 | [kind_([rTypeParam, aTypeParam, cTypeParam]).labeled()],
30 | kind_([rTypeParam, bTypeParam, dTypeParam]),
31 | ),
32 | ),
33 | )
34 |
--------------------------------------------------------------------------------
/src/Endomorphism.ts:
--------------------------------------------------------------------------------
1 | import { HKT, Params } from './HKT.js'
2 | import type { Associative } from './Typeclass/Associative.js'
3 | import type { Identity } from './Typeclass/Identity.js'
4 | import type * as I from './Typeclass/Invariant.js'
5 | import { flow, identity } from './function.js'
6 |
7 | export interface Endomorphism {
8 | (a: A): A
9 | }
10 |
11 | export const makeAssociative = (): Associative> => ({
12 | concat: flow,
13 | })
14 |
15 | export const makeIdentity = (): Identity> => ({
16 | ...makeAssociative(),
17 | id: identity,
18 | })
19 |
20 | export interface EndomorphismHKT extends HKT {
21 | readonly type: Endomorphism
22 | }
23 |
24 | export const Invariant: I.Invariant = {
25 | imap: (fo, fi) => (f) => flow(fi, f, fo),
26 | }
27 |
--------------------------------------------------------------------------------
/src/Typeclass/Eq.test.ts:
--------------------------------------------------------------------------------
1 | import * as fc from 'fast-check'
2 | import { describe, it } from 'vitest'
3 |
4 | import * as L from '../Law/index.js'
5 | import * as B from '../boolean.js'
6 | import { pipe } from '../function.js'
7 | import * as N from '../number.js'
8 |
9 | import * as E from './Eq.js'
10 |
11 | describe(import.meta.url, () => {
12 | describe('Contravariant', () => {
13 | const { identity, associativity } = pipe(
14 | L.number(),
15 | L.Contravariant.testContravariant()(
16 | E.Contravariant,
17 | (a: number) => String(a),
18 | (s: string) => s.length % 2 === 0,
19 | N.Eq,
20 | B.Eq,
21 | (eq: E.Eq, a: A, b: A) => eq.equals(a, b),
22 | B.Eq,
23 | ),
24 | )(fc)
25 |
26 | it('Identity', identity)
27 | it('Associativity', associativity)
28 | })
29 | })
30 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeBoth.tuple.ts:
--------------------------------------------------------------------------------
1 | import { ArrayNode, Dynamic, Kind, Static } from '../AST.js'
2 |
3 | import { AssociativeBoth } from './AssociativeBoth.js'
4 | import { Covariant } from './Covariant.js'
5 | import { derived_, fn_, hkt, kindWithDefaults_, placeholder } from './common.js'
6 |
7 | export const tuple = derived_(
8 | 'tuple',
9 | [AssociativeBoth, Covariant],
10 | fn_(
11 | '',
12 | [new ArrayNode(kindWithDefaults_([new Static('any')])).nonEmpty().labeled('AS')],
13 | [new Static(`AS`).labeled('...values')],
14 | new Kind(hkt, [
15 | placeholder.extract(`AS[number]`),
16 | new Dynamic(
17 | [hkt],
18 | ([hkt]) =>
19 | `{ readonly [K in keyof AS]: ParamOf<${hkt
20 | .split('extends')[0]
21 | .trim()}, AS[K], Params.A> }`,
22 | ),
23 | ]),
24 | ),
25 | )
26 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Divariant.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | cTypeParam,
7 | dTypeParam,
8 | fnLabeled_,
9 | fn_,
10 | interface_,
11 | kind_,
12 | placeholder,
13 | } from './common.js'
14 |
15 | export const node = interface_('Divariant', [
16 | fnLabeled_(
17 | 'dimap',
18 | [aTypeParam, bTypeParam, cTypeParam, dTypeParam],
19 | [
20 | new Dynamic([aTypeParam, bTypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled('f'),
21 | new Dynamic([cTypeParam, dTypeParam] as const, ([c, d]) => `Unary<${c}, ${d}>`).labeled('g'),
22 | ],
23 | fn_(
24 | '',
25 | [placeholder],
26 | [kind_([bTypeParam, cTypeParam]).labeled('kind')],
27 | kind_([aTypeParam, dTypeParam]),
28 | ),
29 | ),
30 | ])
31 |
32 | export const Divariant = node
33 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ForEach.sequence.ts:
--------------------------------------------------------------------------------
1 | import { HKTParam, Kind } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { ForEach } from './ForEach.js'
5 | import { IdentityBoth } from './IdentityBoth.js'
6 | import { aTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
7 |
8 | const hkt2 = new HKTParam(Symbol('T2'), 'T2')
9 | const hkt2Placeholder = hkt2.toPlaceholder()
10 |
11 | export const sequence = derived_(
12 | 'sequence',
13 | [ForEach],
14 | derived_(
15 | '',
16 | [IdentityBoth, Covariant],
17 | fn_(
18 | '',
19 | [placeholder, hkt2Placeholder, aTypeParam],
20 | [kind_([new Kind(hkt2, [hkt2Placeholder, aTypeParam])]).labeled('kind')],
21 | new Kind(hkt2, [hkt2Placeholder, kind_([aTypeParam])]),
22 | ),
23 | hkt2,
24 | ),
25 | )
26 |
27 | export const node = sequence
28 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Bicovariant.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | cTypeParam,
7 | dTypeParam,
8 | fnLabeled_,
9 | fn_,
10 | interface_,
11 | kind_,
12 | placeholder,
13 | } from './common.js'
14 |
15 | export const Bicovariant = interface_('Bicovariant', [
16 | fnLabeled_(
17 | 'bimap',
18 | [aTypeParam, bTypeParam, cTypeParam, dTypeParam],
19 | [
20 | new Dynamic([aTypeParam, bTypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled('f'),
21 | new Dynamic([cTypeParam, dTypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled('g'),
22 | ],
23 | fn_(
24 | '',
25 | [placeholder],
26 | [kind_([aTypeParam, cTypeParam]).labeled('kind')],
27 | kind_([bTypeParam, dTypeParam]),
28 | ),
29 | ),
30 | ])
31 |
32 | export const node = Bicovariant
33 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ForEach.mapAccum.ts:
--------------------------------------------------------------------------------
1 | import { Static, Tuple } from '../AST.js'
2 |
3 | import { ForEach } from './ForEach.js'
4 | import { aTypeParam, bTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const sTypeParam = new Static(`S`)
7 |
8 | export const mapAccum = derived_(
9 | 'mapAccum',
10 | [ForEach],
11 | fn_(
12 | '',
13 | [sTypeParam, aTypeParam, bTypeParam],
14 | [
15 | sTypeParam.labeled('s'),
16 | fnLabeled_(
17 | 'f',
18 | [],
19 | [sTypeParam.labeled('s'), aTypeParam.labeled('a')],
20 | new Tuple([sTypeParam, bTypeParam]),
21 | ),
22 | ],
23 | fn_(
24 | '',
25 | [placeholder],
26 | [kind_([aTypeParam]).labeled()],
27 | new Tuple([sTypeParam, kind_([bTypeParam])]),
28 | ),
29 | ),
30 | )
31 |
32 | export const node = mapAccum
33 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/CovariantWithIndex.map.ts:
--------------------------------------------------------------------------------
1 | import { Static } from '../AST.js'
2 |
3 | import { CovariantWithIndex } from './CovariantWithIndex.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | curriedPlaceholder_,
8 | fnLabeled_,
9 | fn_,
10 | hkt,
11 | kind_,
12 | placeholder,
13 | } from './common.js'
14 |
15 | const kTypeParam = new Static('K')
16 |
17 | export const map = fn_(
18 | 'map',
19 | [hkt, kTypeParam, curriedPlaceholder_(hkt)],
20 | [
21 | CovariantWithIndex.toTypeClass(hkt)
22 | .setParams([kTypeParam, curriedPlaceholder_(hkt)])
23 | .labeled('CI'),
24 | ],
25 | fn_(
26 | '',
27 | [aTypeParam, bTypeParam],
28 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam)],
29 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], kind_([bTypeParam])),
30 | ),
31 | )
32 |
33 | export const node = map
34 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMapWithIndex.ts:
--------------------------------------------------------------------------------
1 | import { Interface, Static } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | curriedPlaceholder_,
7 | fnLabeled_,
8 | fn_,
9 | hkt,
10 | kind_,
11 | placeholder,
12 | } from './common.js'
13 |
14 | export const FoldMapWithIndex = new Interface(
15 | 'FoldMapWithIndex',
16 | [hkt, new Static(`K`), curriedPlaceholder_(hkt)],
17 | [
18 | fnLabeled_(
19 | 'foldMapWithIndex',
20 | [bTypeParam],
21 | [new Static(`Identity`).labeled('ID')],
22 | fn_(
23 | '',
24 | [aTypeParam],
25 | [fnLabeled_('f', [], [new Static(`K`).labeled('k'), aTypeParam.labeled('a')], bTypeParam)],
26 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bTypeParam),
27 | ),
28 | ),
29 | ],
30 | [],
31 | )
32 |
33 | export const node = FoldMapWithIndex
34 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeCompose.compose.ts:
--------------------------------------------------------------------------------
1 | import { AssociativeCompose } from './AssociativeCompose.js'
2 | import { AssociativeFlatten } from './AssociativeFlatten.js'
3 | import { Covariant } from './Covariant.js'
4 | import {
5 | bTypeParam,
6 | cTypeParam,
7 | composed_,
8 | dTypeParam,
9 | fn_,
10 | kindF_,
11 | kindG_,
12 | placeholderF,
13 | placeholderG,
14 | } from './common.js'
15 |
16 | export const compose = composed_(
17 | 'compose',
18 | [AssociativeFlatten, Covariant],
19 | [AssociativeCompose],
20 | fn_(
21 | '',
22 | [placeholderF, placeholderG, cTypeParam, dTypeParam],
23 | [kindF_([kindG_([cTypeParam, dTypeParam])]).labeled('second')],
24 | fn_(
25 | '',
26 | [bTypeParam],
27 | [kindF_([kindG_([bTypeParam, cTypeParam])]).labeled('first')],
28 | kindF_([kindG_([bTypeParam, dTypeParam])]),
29 | ),
30 | ),
31 | )
32 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FoldMap.partitionMap.ts:
--------------------------------------------------------------------------------
1 | import { Static, Tuple } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { FoldMap } from './FoldMap.js'
5 | import { IdentityEither } from './IdentityEither.js'
6 | import { Top } from './Top.js'
7 | import {
8 | aTypeParam,
9 | bTypeParam,
10 | cTypeParam,
11 | derived_,
12 | fnLabeled_,
13 | fn_,
14 | kind_,
15 | placeholder,
16 | } from './common.js'
17 |
18 | export const partitionMap = derived_(
19 | 'partitionMap',
20 | [FoldMap, IdentityEither, Top, Covariant],
21 | fn_(
22 | '',
23 | [aTypeParam, bTypeParam, cTypeParam],
24 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], new Static(`Either`))],
25 | fn_(
26 | '',
27 | [placeholder],
28 | [kind_([aTypeParam]).labeled()],
29 | new Tuple([kind_([bTypeParam]), kind_([cTypeParam])]),
30 | ),
31 | ),
32 | )
33 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Divariant.dimap.ts:
--------------------------------------------------------------------------------
1 | import { Covariant } from './Covariant.js'
2 | import { Divariant } from './Divariant.js'
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | cTypeParam,
7 | composed_,
8 | dTypeParam,
9 | fnLabeled_,
10 | fn_,
11 | kindF_,
12 | kindG_,
13 | placeholderF,
14 | placeholderG,
15 | } from './common.js'
16 |
17 | export const dimap = composed_(
18 | 'dimap',
19 | [Divariant],
20 | [Covariant],
21 | fn_(
22 | '',
23 | [aTypeParam, bTypeParam, cTypeParam, dTypeParam],
24 | [
25 | fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam),
26 | fnLabeled_('g', [], [cTypeParam.labeled('c')], dTypeParam),
27 | ],
28 | fn_(
29 | '',
30 | [placeholderF, placeholderG],
31 | [kindF_([bTypeParam, kindG_([cTypeParam])]).labeled()],
32 | kindF_([aTypeParam, kindG_([dTypeParam])]),
33 | ),
34 | ),
35 | )
36 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/PartitionMap.ts:
--------------------------------------------------------------------------------
1 | import { Static, Tuple } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | cTypeParam,
7 | fnLabeled_,
8 | fn_,
9 | interface_,
10 | kind_,
11 | placeholder,
12 | } from './common.js'
13 |
14 | export const PartitionMap = interface_(
15 | 'PartitionMap',
16 | [
17 | fnLabeled_(
18 | 'partitionMap',
19 | [aTypeParam, bTypeParam, cTypeParam],
20 | [
21 | fnLabeled_(
22 | 'f',
23 | [],
24 | [aTypeParam.labeled('a')],
25 | new Static(`Either<${bTypeParam.type}, ${cTypeParam.type}>`),
26 | ),
27 | ],
28 | fn_(
29 | '',
30 | [placeholder],
31 | [kind_([aTypeParam]).labeled('kind')],
32 | new Tuple([kind_([bTypeParam]), kind_([cTypeParam])]),
33 | ),
34 | ),
35 | ],
36 | [],
37 | )
38 |
39 | export const node = PartitionMap
40 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ReduceWithIndex.ts:
--------------------------------------------------------------------------------
1 | import { Interface, Static } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | curriedPlaceholder_,
7 | fnLabeled_,
8 | fn_,
9 | hkt,
10 | kind_,
11 | placeholder,
12 | } from './common.js'
13 |
14 | export const ReduceWithIndex = new Interface(
15 | 'ReduceWithIndex',
16 | [hkt, new Static(`K`), curriedPlaceholder_(hkt)],
17 | [
18 | fnLabeled_(
19 | 'reduceWithIndex',
20 | [bTypeParam, aTypeParam],
21 | [
22 | bTypeParam.labeled('b'),
23 | fnLabeled_(
24 | 'f',
25 | [],
26 | [new Static(`K`).labeled('k'), bTypeParam.labeled('b'), aTypeParam.labeled('a')],
27 | bTypeParam,
28 | ),
29 | ],
30 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bTypeParam),
31 | ),
32 | ],
33 | [],
34 | )
35 |
36 | export const node = ReduceWithIndex
37 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeEither.either.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { AssociativeEither } from './AssociativeEither.js'
4 | import { AssociativeFlatten } from './AssociativeFlatten.js'
5 | import { Covariant } from './Covariant.js'
6 | import {
7 | aTypeParam,
8 | bTypeParam,
9 | composed_,
10 | fn_,
11 | kindF_,
12 | kindG_,
13 | placeholderF,
14 | placeholderG,
15 | } from './common.js'
16 |
17 | export const either = composed_(
18 | 'either',
19 | [AssociativeFlatten, Covariant],
20 | [AssociativeEither],
21 | fn_(
22 | '',
23 | [placeholderF, placeholderG, bTypeParam],
24 | [kindF_([kindG_([bTypeParam])]).labeled('second')],
25 | fn_(
26 | '',
27 | [aTypeParam],
28 | [kindF_([kindG_([aTypeParam])]).labeled('first')],
29 | kindF_([kindG_([new Dynamic([aTypeParam, bTypeParam], ([a, b]) => `Either<${a}, ${b}>`)])]),
30 | ),
31 | ),
32 | )
33 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FilterMapWithIndex.ts:
--------------------------------------------------------------------------------
1 | import { Interface, Static } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | curriedPlaceholder_,
7 | fnLabeled_,
8 | fn_,
9 | hkt,
10 | kind_,
11 | placeholder,
12 | } from './common.js'
13 |
14 | const kTypeParam = new Static(`K`)
15 |
16 | export const FilterMapWithIndex = new Interface(
17 | 'FilterMapWithIndex',
18 | [hkt, kTypeParam, curriedPlaceholder_(hkt)],
19 | [
20 | fnLabeled_(
21 | 'filterMapWithIndex',
22 | [aTypeParam, bTypeParam],
23 | [
24 | fnLabeled_(
25 | 'f',
26 | [],
27 | [kTypeParam.labeled('k'), aTypeParam.labeled('a')],
28 | new Static(`Maybe`),
29 | ),
30 | ],
31 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], kind_([bTypeParam])),
32 | ),
33 | ],
34 | [],
35 | )
36 |
37 | export const node = FilterMapWithIndex
38 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ReduceRightWithIndex.ts:
--------------------------------------------------------------------------------
1 | import { Interface, Static } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | curriedPlaceholder_,
7 | fnLabeled_,
8 | fn_,
9 | hkt,
10 | kind_,
11 | placeholder,
12 | } from './common.js'
13 |
14 | export const ReduceRightWithIndex = new Interface(
15 | 'ReduceRightWithIndex',
16 | [hkt, new Static(`K`), curriedPlaceholder_(hkt)],
17 | [
18 | fnLabeled_(
19 | 'reduceRightWithIndex',
20 | [bTypeParam, aTypeParam],
21 | [
22 | bTypeParam.labeled('b'),
23 | fnLabeled_(
24 | 'f',
25 | [],
26 | [new Static(`K`).labeled('k'), aTypeParam.labeled('a'), bTypeParam.labeled('b')],
27 | bTypeParam,
28 | ),
29 | ],
30 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], bTypeParam),
31 | ),
32 | ],
33 | [],
34 | )
35 |
36 | export const node = ReduceRightWithIndex
37 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeEither.eitherWith.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { AssociativeEither } from './AssociativeEither.js'
4 | import { Contravariant } from './Contravariant.js'
5 | import {
6 | aTypeParam,
7 | bTypeParam,
8 | cTypeParam,
9 | derived_,
10 | fnLabeled_,
11 | fn_,
12 | kind_,
13 | placeholder,
14 | } from './common.js'
15 |
16 | export const eitherWith = derived_(
17 | 'eitherWith',
18 | [AssociativeEither, Contravariant],
19 | fn_(
20 | '',
21 | [placeholder, bTypeParam, cTypeParam, aTypeParam],
22 | [
23 | kind_([bTypeParam]).labeled('b'),
24 | fnLabeled_(
25 | 'f',
26 | [],
27 | [cTypeParam.labeled('c')],
28 | new Dynamic([aTypeParam, bTypeParam], ([a, b]) => `Either<${a}, ${b}>`),
29 | ),
30 | ],
31 | fn_('', [], [kind_([aTypeParam]).labeled('a')], kind_([cTypeParam])),
32 | ),
33 | )
34 |
35 | export const node = eitherWith
36 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ForEach.forEach.ts:
--------------------------------------------------------------------------------
1 | import { Covariant } from './Covariant.js'
2 | import { ForEach } from './ForEach.js'
3 | import { IdentityBoth } from './IdentityBoth.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | composed_,
8 | derived_,
9 | fnLabeled_,
10 | fn_,
11 | kindF_,
12 | kindG_,
13 | kind_,
14 | placeholder,
15 | placeholderF,
16 | placeholderG,
17 | } from './common.js'
18 |
19 | export const forEach = composed_(
20 | 'forEach',
21 | [ForEach],
22 | [ForEach],
23 | derived_(
24 | '',
25 | [IdentityBoth, Covariant],
26 | fn_(
27 | '',
28 | [aTypeParam, placeholder, bTypeParam],
29 | [fnLabeled_('f', [], [aTypeParam.labeled('a')], kind_([bTypeParam]))],
30 | fn_(
31 | '',
32 | [placeholderF, placeholderG],
33 | [kindF_([kindG_([aTypeParam])]).labeled('kind')],
34 | kind_([kindF_([kindG_([bTypeParam])])]),
35 | ),
36 | ),
37 | ),
38 | )
39 |
--------------------------------------------------------------------------------
/src/Typeclass/Identity.test.ts:
--------------------------------------------------------------------------------
1 | import * as fc from 'fast-check'
2 | import { describe, it } from 'vitest'
3 |
4 | import * as L from '../Law/index.js'
5 | import * as M from '../Maybe.js'
6 | import * as B from '../boolean.js'
7 | import * as N from '../number.js'
8 | import * as S from '../string.js'
9 |
10 | import { fromIdentityEitherCovariant } from './Identity.js'
11 |
12 | describe(import.meta.url, () => {
13 | describe(fromIdentityEitherCovariant.name, () => {
14 | it('creates an Identity instance', () => {
15 | const makeIdentity = fromIdentityEitherCovariant({
16 | ...M.IdentityEither,
17 | ...M.Covariant,
18 | })
19 |
20 | L.Identity.testIdentity(makeIdentity(), M.makeEq(N.Eq))(L.Maybe(L.number()))(fc)
21 | L.Identity.testIdentity(makeIdentity(), M.makeEq(S.Eq))(L.Maybe(L.string()))(fc)
22 | L.Identity.testIdentity(makeIdentity(), M.makeEq(B.Eq))(L.Maybe(L.boolean))(fc)
23 | })
24 | })
25 | })
26 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/CovariantWithIndex.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, FunctionSignature, Interface, Static } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | curriedPlaceholder_,
7 | fnLabeled_,
8 | hkt,
9 | kind_,
10 | placeholder,
11 | } from './common.js'
12 |
13 | export const kTypeParam = new Static('K')
14 |
15 | export const node = new Interface(
16 | 'CovariantWithIndex',
17 | [hkt, kTypeParam, curriedPlaceholder_(hkt)],
18 | [
19 | fnLabeled_(
20 | 'mapWithIndex',
21 | [aTypeParam, bTypeParam],
22 | [
23 | new Dynamic(
24 | [aTypeParam, bTypeParam, kTypeParam] as const,
25 | ([a, b, k]) => `(index: ${k}, a: ${a}) => ${b}`,
26 | ).labeled('f'),
27 | ],
28 | new FunctionSignature(
29 | '',
30 | [placeholder],
31 | [kind_([aTypeParam]).labeled('kind')],
32 | kind_([bTypeParam]),
33 | ),
34 | ),
35 | ],
36 | )
37 |
38 | export const CovariantWithIndex = node
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
39 | # generated files
40 | build
41 | dist
42 | esm
43 | cjs
44 | umd
45 | lib
46 | .tmp
47 | .cache-loader
48 |
49 | # other stuff
50 | src/test.ts
51 | .DS_STORE
52 | .vscode
53 | .fusebox
54 | .history
55 | tsconfig*.tsbuildinfo
56 | .rpt2_cache
57 | .eslintcache
58 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Bicovariant.bimap.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic } from '../AST.js'
2 |
3 | import { Bicovariant } from './Bicovariant.js'
4 | import { Covariant } from './Covariant.js'
5 | import {
6 | aTypeParam,
7 | bTypeParam,
8 | cTypeParam,
9 | composed_,
10 | dTypeParam,
11 | fn_,
12 | kindF_,
13 | kindG_,
14 | placeholderF,
15 | placeholderG,
16 | } from './common.js'
17 |
18 | export const bimap = composed_(
19 | 'bimap',
20 | [Covariant],
21 | [Bicovariant],
22 | fn_(
23 | '',
24 | [aTypeParam, bTypeParam, cTypeParam, dTypeParam],
25 | [
26 | new Dynamic([aTypeParam, bTypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled('f'),
27 | new Dynamic([cTypeParam, dTypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled('g'),
28 | ],
29 | fn_(
30 | '',
31 | [placeholderF, placeholderG],
32 | [kindF_([kindG_([aTypeParam, cTypeParam])]).labeled()],
33 | kindF_([kindG_([bTypeParam, dTypeParam])]),
34 | ),
35 | ),
36 | )
37 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Law/testCovariant.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, Static } from '../../AST.js'
2 | import { Covariant } from '../Covariant.js'
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | cTypeParam,
7 | curriedPlaceholder_,
8 | fnLabeled_,
9 | fn_,
10 | hkt,
11 | kind_,
12 | placeholder,
13 | } from '../common.js'
14 |
15 | export const testCovariant = fn_(
16 | 'testCovariant',
17 | [hkt, curriedPlaceholder_(hkt), aTypeParam, bTypeParam, cTypeParam, placeholder],
18 | [
19 | Covariant.toTypeClass(hkt).labeled('C'),
20 | fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam),
21 | fnLabeled_('g', [], [bTypeParam.labeled('b')], cTypeParam),
22 | new Dynamic([kind_([cTypeParam])], ([kind]) => `Eq<${kind}>`).labeled(`Eq?`),
23 | ],
24 | fn_(
25 | '',
26 | [],
27 | [new Dynamic([kind_([aTypeParam])], ([k]) => `Arbitrary.Arbitrary<${k}>`).labeled(`Arb`)],
28 | fn_('', [], [new Static(`typeof import('fast-check')`).labeled('fc')], new Static(`void`)),
29 | ),
30 | )
31 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeBoth.bothWith.ts:
--------------------------------------------------------------------------------
1 | import { IntersectionNode, Tuple } from '../AST.js'
2 |
3 | import { AssociativeBoth } from './AssociativeBoth.js'
4 | import { Contravariant } from './Contravariant.js'
5 | import {
6 | aTypeParam,
7 | bTypeParam,
8 | cTypeParam,
9 | curriedPlaceholder_,
10 | fnLabeled_,
11 | fn_,
12 | hkt,
13 | kind_,
14 | placeholder,
15 | } from './common.js'
16 |
17 | export const bothWith = fn_(
18 | 'bothWith',
19 | [hkt, curriedPlaceholder_(hkt)],
20 | [
21 | new IntersectionNode(AssociativeBoth.toTypeClass(hkt), Contravariant.toTypeClass(hkt)).labeled(
22 | 'AB',
23 | ),
24 | ],
25 | fn_(
26 | '',
27 | [placeholder, bTypeParam, cTypeParam, aTypeParam],
28 | [
29 | kind_([bTypeParam]).labeled('b'),
30 | fnLabeled_('f', [], [cTypeParam.labeled('c')], new Tuple([aTypeParam, bTypeParam])),
31 | ],
32 | fn_('', [], [kind_([aTypeParam]).labeled('a')], kind_([cTypeParam])),
33 | ),
34 | )
35 |
36 | export const node = bothWith
37 |
--------------------------------------------------------------------------------
/src/number.test.ts:
--------------------------------------------------------------------------------
1 | import * as fc from 'fast-check'
2 | import { describe } from 'vitest'
3 |
4 | import * as L from './Law/index.js'
5 | import { testAllDataLaws } from './Law/internal-test-all-laws.js'
6 | import * as N from './number.js'
7 |
8 | describe(import.meta.url, () => {
9 | testAllDataLaws({
10 | name: 'Number Instances',
11 | fc,
12 | // Only constrained because really large numbers used in multiplication w/ JavaScript aren't exactly deterministic
13 | Arbitrary: L.number({ min: -10000, max: 10000 }),
14 | Eq: {
15 | number: N.Eq,
16 | },
17 | Ord: {
18 | number: N.Ord,
19 | },
20 | Associative: {
21 | Sum: [N.AssociativeSum, N.Eq],
22 | Product: [N.AssociativeProduct, N.Eq],
23 | },
24 | Commutative: {
25 | Sum: [N.CommutativeSum, N.Eq],
26 | Product: [N.CommutativeProduct, N.Eq],
27 | },
28 | Identity: {
29 | Sum: [N.IdentitySum, N.Eq],
30 | Product: [N.IdentityProduct, N.Eq],
31 | },
32 | Inverse: {
33 | Sum: [N.Inverse, N.Eq],
34 | },
35 | })
36 | })
37 |
--------------------------------------------------------------------------------
/src/Law/Identity.ts:
--------------------------------------------------------------------------------
1 | import { DeepEquals, Eq } from '../Typeclass/Eq.js'
2 | import { Identity } from '../Typeclass/Identity.js'
3 | import { pipe } from '../function.js'
4 |
5 | import * as Arbitrary from './Arbitrary.js'
6 |
7 | export function testIdentity(I: Identity, Eq: Eq = DeepEquals) {
8 | const left = testLeftIdentity(I, Eq)
9 | const right = testRightIdentity(I, Eq)
10 |
11 | return (Arb: Arbitrary.Arbitrary) => (fc: typeof import('fast-check')) => ({
12 | left: () => left(Arb).property(fc),
13 | right: () => right(Arb).property(fc),
14 | })
15 | }
16 |
17 | export function testLeftIdentity(I: Identity, Eq: Eq = DeepEquals) {
18 | return (Arb: Arbitrary.Arbitrary) =>
19 | pipe(
20 | Arb,
21 | Arbitrary.toProperty((a) => Eq.equals(I.concat(a, I.id), a)),
22 | )
23 | }
24 |
25 | export function testRightIdentity(I: Identity, Eq: Eq = DeepEquals) {
26 | return (Arb: Arbitrary.Arbitrary) =>
27 | pipe(
28 | Arb,
29 | Arbitrary.toProperty((a) => Eq.equals(I.concat(I.id, a), a)),
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/PartitionMapWithIndex.ts:
--------------------------------------------------------------------------------
1 | import { Interface, Static, Tuple } from '../AST.js'
2 |
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | cTypeParam,
7 | curriedPlaceholder_,
8 | fnLabeled_,
9 | fn_,
10 | hkt,
11 | kind_,
12 | placeholder,
13 | } from './common.js'
14 |
15 | export const PartitionMapWithIndex = new Interface(
16 | 'PartitionMapWithIndex',
17 | [hkt, new Static(`K`), curriedPlaceholder_(hkt)],
18 | [
19 | fnLabeled_(
20 | 'partitionMapWithIndex',
21 | [aTypeParam, bTypeParam, cTypeParam],
22 | [
23 | fnLabeled_(
24 | 'f',
25 | [],
26 | [new Static(`K`).labeled('k'), aTypeParam.labeled('a')],
27 | new Static(`Either<${bTypeParam.type}, ${cTypeParam.type}>`),
28 | ),
29 | ],
30 | fn_(
31 | '',
32 | [placeholder],
33 | [kind_([aTypeParam]).labeled('kind')],
34 | new Tuple([kind_([bTypeParam]), kind_([cTypeParam])]),
35 | ),
36 | ),
37 | ],
38 | [],
39 | )
40 |
41 | export const node = PartitionMapWithIndex
42 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/IdentityBoth.struct.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, Kind, Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { IdentityBoth } from './IdentityBoth.js'
5 | import { derived_, fn_, hkt, placeholder, placeholderWithDefaults } from './common.js'
6 |
7 | export const struct = derived_(
8 | 'struct',
9 | [IdentityBoth, Covariant],
10 | fn_(
11 | '',
12 | [
13 | new Dynamic(
14 | [placeholderWithDefaults],
15 | ([...params]) =>
16 | `A extends Readonly 1 ? params.length : ''
18 | } s.split('=')[1])
21 | .join(', ')}${params.length > 1 ? ', ' : ''}any>>>`,
22 | ),
23 | ],
24 | [new Static(`A`).labeled('values')],
25 | new Kind(hkt, [
26 | placeholder.extract(`A[string]`),
27 | new Dynamic([hkt], ([hkt]) => `{ readonly [K in keyof A]: ParamOf<${hkt}, A[K], Params.A> }`),
28 | ]),
29 | ),
30 | )
31 |
32 | export const node = struct
33 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/FilterMap.filter.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, Static } from '../AST.js'
2 |
3 | import { FilterMap } from './FilterMap.js'
4 | import { aTypeParam, bTypeParam, derived_, fn_, kind_, placeholder } from './common.js'
5 |
6 | const pred = fn_(
7 | '',
8 | [aTypeParam],
9 | [new Static(`Predicate`).labeled('predicate')],
10 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], kind_([aTypeParam])),
11 | )
12 |
13 | const refine = fn_(
14 | '',
15 | [aTypeParam, new Static(`B extends A`)],
16 | [new Static(`Refinement`).labeled('refinement')],
17 | fn_('', [placeholder], [kind_([aTypeParam]).labeled('kind')], kind_([bTypeParam])),
18 | )
19 |
20 | export const filter = derived_(
21 | 'filter',
22 | [FilterMap],
23 | new Dynamic(
24 | [pred, refine],
25 | ([p, r]) => `{\n ${printOverloadFunction(r)}\n ${printOverloadFunction(p)}}`,
26 | ),
27 | )
28 |
29 | function printOverloadFunction(f: string) {
30 | const i = f.indexOf('=>')
31 |
32 | return f.slice(0, i).trim() + `: ` + f.slice(i + 2).trim()
33 | }
34 |
35 | export const node = filter
36 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * as Array from './Array.js'
2 | export * as boolean from './boolean.js'
3 | export * as Branded from './Branded.js'
4 | export * as Data from './Data.js'
5 | export * as Either from './Either.js'
6 | export * as Endomorphism from './Endomorphism.js'
7 | export * as Id from './Id.js'
8 | export * as Map from './Map.js'
9 | export * as Match from './Match.js'
10 | export * as Maybe from './Maybe.js'
11 | export * as NonEmptyArray from './NonEmptyArray.js'
12 | export * as number from './number.js'
13 | export * as Predicate from './Predicate.js'
14 | export * as Progress from './Progress.js'
15 | export * as Record from './Record.js'
16 | export * as Refinement from './Refinement.js'
17 | export * as RoseTree from './RoseTree.js'
18 | export * as Set from './Set.js'
19 | export * as string from './string.js'
20 | export * as struct from './struct.js'
21 | export * as These from './These.js'
22 | export * as Tree from './Tree.js'
23 | export * as Tuple from './Tuple.js'
24 | export * as Typeclass from './Typeclass/index.js'
25 | export * as Unary from './Unary.js'
26 | export * from './function.js'
27 | export * from './HKT.js'
28 | export * from './logical.js'
29 |
--------------------------------------------------------------------------------
/src/Law/AssociativeBoth.ts:
--------------------------------------------------------------------------------
1 | import { HKT, Kind } from '../HKT.js'
2 | import { AssociativeBoth } from '../Typeclass/AssociativeBoth.js'
3 | import { Covariant } from '../Typeclass/Covariant.js'
4 | import { DeepEquals, Eq } from '../Typeclass/Eq.js'
5 | import { pipe } from '../function.js'
6 |
7 | import * as Arbitrary from './Arbitrary.js'
8 |
9 | export function testCovariantAssociativeBoth(
10 | ABC: AssociativeBoth & Covariant,
11 | fab: Kind B>,
12 | fbc: Kind C>,
13 | E: Eq> = DeepEquals,
14 | ) {
15 | return (A: Arbitrary.Arbitrary>) =>
16 | pipe(
17 | A,
18 | Arbitrary.map((k: Kind) => {
19 | return [
20 | pipe(
21 | k,
22 | ABC.both(fab),
23 | ABC.both(fbc),
24 | ABC.map(([[a, ab], bc]) => bc(ab(a))),
25 | ),
26 | pipe(
27 | k,
28 | ABC.both(fbc),
29 | ABC.both(fab),
30 | ABC.map(([[a, bc], ab]) => bc(ab(a))),
31 | ),
32 | ] as const
33 | }),
34 | Arbitrary.toProperty(([a, b]) => E.equals(a, b)),
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/PartitionMapWithIndex.partitionMap.ts:
--------------------------------------------------------------------------------
1 | import { Static, Tuple } from '../AST.js'
2 |
3 | import { PartitionMapWithIndex } from './PartitionMapWithIndex.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | cTypeParam,
8 | curriedPlaceholder_,
9 | fnLabeled_,
10 | fn_,
11 | hkt,
12 | kind_,
13 | placeholder,
14 | } from './common.js'
15 |
16 | const kTypeParam = new Static('K')
17 |
18 | export const partitionMap = fn_(
19 | 'partitionMap',
20 | [hkt, kTypeParam, curriedPlaceholder_(hkt)],
21 | [
22 | PartitionMapWithIndex.toTypeClass(hkt)
23 | .setParams([kTypeParam, curriedPlaceholder_(hkt)])
24 | .labeled('PMI'),
25 | ],
26 | fn_(
27 | '',
28 | [aTypeParam, bTypeParam, cTypeParam],
29 | [
30 | fnLabeled_(
31 | 'f',
32 | [],
33 | [aTypeParam.labeled('a')],
34 | new Static(`Either<${bTypeParam.type}, ${cTypeParam.type}>`),
35 | ),
36 | ],
37 | fn_(
38 | '',
39 | [placeholder],
40 | [kind_([aTypeParam]).labeled('kind')],
41 | new Tuple([kind_([bTypeParam]), kind_([cTypeParam])]),
42 | ),
43 | ),
44 | )
45 |
46 | export const node = partitionMap
47 |
--------------------------------------------------------------------------------
/src/Typeclass/Associative.test.ts:
--------------------------------------------------------------------------------
1 | import { deepStrictEqual } from 'node:assert'
2 |
3 | import { describe, it } from 'vitest'
4 |
5 | import * as A from './Associative.js'
6 |
7 | describe(import.meta.url, () => {
8 | describe('constant', () => {
9 | it('creates an Associative instance which always returns a paraticular value', () => {
10 | deepStrictEqual(A.constant(3).concat(1, 2), 3)
11 | })
12 | })
13 |
14 | describe('struct', () => {
15 | it('creates an Associative for a structure', () => {
16 | const { concat } = A.struct({
17 | a: A.First,
18 | b: A.Second,
19 | })
20 |
21 | deepStrictEqual(concat({ a: 1, b: 2 }, { a: 3, b: 4 }), { a: 1, b: 4 })
22 | })
23 | })
24 |
25 | describe('tuple', () => {
26 | it('creates an Associative for a tuple', () => {
27 | const { concat } = A.tuple(A.First, A.Second)
28 |
29 | deepStrictEqual(concat([1, 2], [3, 4]), [1, 4])
30 | })
31 | })
32 |
33 | describe('intercalate', () => {
34 | it('creates an Associative instance ', () => {
35 | const { concat } = A.intercalate(3)({ concat: (x, y) => x + y })
36 |
37 | deepStrictEqual(concat(1, 2), 6)
38 | })
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/AssociativeFlatten.bind.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, Static } from '../AST.js'
2 |
3 | import { AssociativeFlatten } from './AssociativeFlatten.js'
4 | import { Covariant } from './Covariant.js'
5 | import { bTypeParam, derived_, fnLabeled_, fn_, kind_, placeholder } from './common.js'
6 |
7 | const aTypeParam = new Static(`A extends Readonly>`)
8 |
9 | export const nameTypeParam = new Static('N extends string')
10 |
11 | export const node = derived_(
12 | 'bind',
13 | [AssociativeFlatten, Covariant],
14 | fn_(
15 | '',
16 | [nameTypeParam, aTypeParam, placeholder, bTypeParam],
17 | [
18 | new Dynamic(
19 | [nameTypeParam, aTypeParam],
20 | ([name, a]) => `Exclude<${name}, keyof ${a}>`,
21 | ).labeled('name'),
22 | fnLabeled_('f', [], [aTypeParam.labeled('a')], kind_([bTypeParam])),
23 | ],
24 | fn_(
25 | '',
26 | [],
27 | [kind_([aTypeParam]).labeled('kind')],
28 | kind_([
29 | new Dynamic(
30 | [aTypeParam, bTypeParam],
31 | ([a, b]) => `{ readonly [K in keyof ${a} | N]: K extends keyof ${a} ? ${a}[K] : ${b} }`,
32 | ),
33 | ]),
34 | ),
35 | ),
36 | )
37 |
--------------------------------------------------------------------------------
/src/common.ts:
--------------------------------------------------------------------------------
1 | import type { HKT2, Params } from './HKT.js'
2 | import type { Covariant2 } from './Typeclass/Covariant.js'
3 | import type { Identity } from './Typeclass/Identity.js'
4 | import type { IdentityBoth2 } from './Typeclass/IdentityBoth.js'
5 |
6 | export type Include = A extends B ? A : never
7 |
8 | export type State = (s: S) => readonly [S, A]
9 |
10 | export interface StateHKT extends HKT2 {
11 | readonly type: State
12 | }
13 |
14 | export const makeStateIdentity = (ID: Identity): Identity> => ({
15 | id: (s) => [s, ID.id],
16 | concat: (first, second) => (s) => {
17 | const [s2, a1] = first(s)
18 | const [s3, a2] = second(s2)
19 |
20 | return [s3, ID.concat(a1, a2)]
21 | },
22 | })
23 |
24 | export const IdentityBothState: IdentityBoth2 = {
25 | top: (s) => [s, []],
26 | both: (second) => (first) => (s) => {
27 | const [s2, b1] = first(s)
28 | const [s3, b2] = second(s2)
29 |
30 | return [s3, [b1, b2]] as const
31 | },
32 | }
33 |
34 | export const CovariantState: Covariant2 = {
35 | map: (f) => (state) => (s) => {
36 | const [s2, a] = state(s)
37 |
38 | return [s2, f(a)]
39 | },
40 | }
41 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ForEach.compacted.ts:
--------------------------------------------------------------------------------
1 | import { HKTParam, Kind, Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { ForEach } from './ForEach.js'
5 | import { IdentityBoth } from './IdentityBoth.js'
6 | import { Compact } from './Compact.js'
7 | import {
8 | aTypeParam,
9 | bTypeParam,
10 | derived_,
11 | fnLabeled_,
12 | fn_,
13 | kind_,
14 | placeholder,
15 | } from './common.js'
16 |
17 | const hkt2 = new HKTParam(Symbol('T2'), 'T2')
18 |
19 | export const compacted = derived_(
20 | 'compacted',
21 | [ForEach, Compact],
22 | derived_(
23 | '',
24 | [IdentityBoth, Covariant],
25 | fn_(
26 | '',
27 | [aTypeParam,hkt2.toPlaceholder(), bTypeParam],
28 | [
29 | fnLabeled_(
30 | 'f',
31 | [],
32 | [aTypeParam.labeled('a')],
33 | new Kind(hkt2, [hkt2.toPlaceholder(), new Static(`Maybe`)]),
34 | ),
35 | ],
36 | fn_(
37 | '',
38 | [placeholder],
39 | [kind_([aTypeParam]).labeled()],
40 | new Kind(hkt2, [
41 | hkt2.toPlaceholder(),
42 | kind_([bTypeParam]),
43 | ]),
44 | ),
45 | ),
46 | hkt2,
47 | ),
48 | )
49 |
50 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Law/testFilterMap.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, ObjectNode, Static } from '../../AST.js'
2 | import { FilterMap } from '../FilterMap.js'
3 | import {
4 | aTypeParam,
5 | boolean_,
6 | curriedPlaceholder_,
7 | fnLabeled_,
8 | fn_,
9 | hkt,
10 | kind_,
11 | placeholder,
12 | } from '../common.js'
13 |
14 | export const testFilterMap = fn_(
15 | 'testFilterMap',
16 | [hkt, curriedPlaceholder_(hkt), aTypeParam, placeholder],
17 | [
18 | FilterMap.toTypeClass(hkt).labeled('FM'),
19 | fnLabeled_('f', [], [aTypeParam.labeled('a')], boolean_),
20 | fnLabeled_('g', [], [aTypeParam.labeled('b')], boolean_),
21 | new Dynamic([kind_([aTypeParam])], ([kind]) => `Eq<${kind}>`).labeled(`Eq?`),
22 | ],
23 | fn_(
24 | '',
25 | [],
26 | [new Dynamic([kind_([aTypeParam])], ([k]) => `Arbitrary.Arbitrary<${k}>`).labeled(`Arb`)],
27 | fn_(
28 | '',
29 | [],
30 | [new Static(`typeof import('fast-check')`).labeled('fc')],
31 | new ObjectNode([
32 | new Static(`() => void`).labeled('identity'),
33 | new Static(`() => void`).labeled('distributivity'),
34 | new Static(`() => void`).labeled('annihilation'),
35 | ]),
36 | ),
37 | ),
38 | )
39 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ForEach.ts:
--------------------------------------------------------------------------------
1 | import { HKTParam, Kind } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { IdentityBoth } from './IdentityBoth.js'
5 | import {
6 | aTypeParam,
7 | bTypeParam,
8 | derived_,
9 | fnLabeled_,
10 | fn_,
11 | interface_,
12 | kind_,
13 | placeholder,
14 | } from './common.js'
15 |
16 | const hkt2 = new HKTParam(Symbol('T2'), 'T2')
17 | const hkt2Placeholder = hkt2.toPlaceholder()
18 |
19 | export const ForEach = interface_(
20 | 'ForEach',
21 | [
22 | derived_(
23 | '',
24 | [IdentityBoth, Covariant],
25 | fn_(
26 | '',
27 | [aTypeParam, hkt2Placeholder, bTypeParam],
28 | [
29 | fnLabeled_(
30 | 'f',
31 | [],
32 | [aTypeParam.labeled('a')],
33 | new Kind(hkt2, [hkt2Placeholder, bTypeParam]),
34 | ),
35 | ],
36 | fn_(
37 | '',
38 | [placeholder],
39 | [kind_([aTypeParam]).labeled('kind')],
40 | new Kind(hkt2, [hkt2Placeholder, kind_([bTypeParam])]),
41 | ),
42 | ),
43 | hkt2,
44 | ).labeled('forEach'),
45 | ],
46 | [Covariant],
47 | )
48 |
49 | export const node = ForEach
50 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ForEachWithIndex.forEach.ts:
--------------------------------------------------------------------------------
1 | import { HKTParam, Kind, Static } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { ForEachWithIndex } from './ForEachWithIndex.js'
5 | import { IdentityBoth } from './IdentityBoth.js'
6 | import {
7 | aTypeParam,
8 | bTypeParam,
9 | derived_,
10 | fnLabeled_,
11 | fn_,
12 | hkt,
13 | kind_,
14 | placeholder,
15 | } from './common.js'
16 |
17 | const hkt2 = new HKTParam(Symbol('T2'), 'T2')
18 | const hkt2Placeholder = hkt2.toPlaceholder()
19 |
20 | export const forEach = derived_(
21 | 'forEach',
22 | [ForEachWithIndex],
23 | derived_(
24 | '',
25 | [IdentityBoth, Covariant],
26 | fn_(
27 | '',
28 | [aTypeParam, hkt2Placeholder, bTypeParam],
29 | [
30 | fnLabeled_(
31 | 'f',
32 | [],
33 | [aTypeParam.labeled('a')],
34 | new Kind(hkt2, [hkt2Placeholder, bTypeParam]),
35 | ),
36 | ],
37 | fn_(
38 | '',
39 | [placeholder],
40 | [kind_([aTypeParam]).labeled('kind')],
41 | new Kind(hkt2, [hkt2Placeholder, kind_([bTypeParam])]),
42 | ),
43 | ),
44 | hkt2,
45 | ),
46 | hkt,
47 | [new Static('K')],
48 | )
49 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Trivariant.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, Static } from '../AST.js'
2 |
3 | import { fnLabeled_, fn_, interface_, kind_, placeholder } from './common.js'
4 |
5 | const r1TypeParam = new Static(`R1`)
6 | const r2TypeParam = new Static(`R2`)
7 |
8 | const e1TypeParam = new Static(`E1`)
9 | const e2TypeParam = new Static(`E2`)
10 |
11 | const a1TypeParam = new Static(`A1`)
12 | const a2TypeParam = new Static(`A2`)
13 |
14 | export const Trivariant = interface_('Trivariant', [
15 | fnLabeled_(
16 | 'trimap',
17 | [r1TypeParam, r2TypeParam, e1TypeParam, e2TypeParam, a1TypeParam, a2TypeParam],
18 | [
19 | new Dynamic([r1TypeParam, r2TypeParam] as const, ([a, b]) => `Unary<${a}, ${b}>`).labeled(
20 | 'f',
21 | ),
22 | new Dynamic([e1TypeParam, e2TypeParam] as const, ([c, d]) => `Unary<${c}, ${d}>`).labeled(
23 | 'g',
24 | ),
25 | new Dynamic([a1TypeParam, a2TypeParam] as const, ([e, f]) => `Unary<${e}, ${f}>`).labeled(
26 | 'h',
27 | ),
28 | ],
29 | fn_(
30 | '',
31 | [placeholder],
32 | [kind_([r2TypeParam, e1TypeParam, a1TypeParam]).labeled('kind')],
33 | kind_([r1TypeParam, e2TypeParam, a2TypeParam]),
34 | ),
35 | ),
36 | ])
37 |
--------------------------------------------------------------------------------
/src/Law/Eq.ts:
--------------------------------------------------------------------------------
1 | import { Eq } from '../Typeclass/Eq.js'
2 | import { pipe } from '../function.js'
3 |
4 | import * as Arbitrary from './Arbitrary.js'
5 |
6 | export function testEq(E: Eq) {
7 | return (Arb: Arbitrary.Arbitrary) => (fc: typeof import('fast-check')) => ({
8 | reflexivity: () => testEqReflexivity(E)(Arb).property(fc),
9 | symmetry: () => testEqSymmetry(E)(Arb).property(fc),
10 | transitivity: () => testEqTransitivity(E)(Arb).property(fc),
11 | })
12 | }
13 |
14 | export function testEqReflexivity(E: Eq) {
15 | return (Arb: Arbitrary.Arbitrary) =>
16 | pipe(
17 | Arb,
18 | Arbitrary.toProperty((a) => E.equals(a, a)),
19 | )
20 | }
21 |
22 | export function testEqSymmetry(E: Eq) {
23 | return (Arb: Arbitrary.Arbitrary) =>
24 | pipe(
25 | Arbitrary.tuple(Arb, Arb),
26 | Arbitrary.toProperty(([a, b]) => E.equals(a, b) === E.equals(b, a)),
27 | )
28 | }
29 |
30 | export function testEqTransitivity(E: Eq) {
31 | return (Arb: Arbitrary.Arbitrary) =>
32 | pipe(
33 | Arbitrary.tuple(Arb, Arb, Arb),
34 | Arbitrary.toProperty(
35 | ([a, b, c]) => (E.equals(a, b) && E.equals(b, c)) === (E.equals(a, b) && E.equals(a, c)),
36 | ),
37 | )
38 | }
39 |
--------------------------------------------------------------------------------
/src/Typeclass/Concat.test.ts:
--------------------------------------------------------------------------------
1 | import { deepStrictEqual } from 'node:assert'
2 |
3 | import { describe, it } from 'vitest'
4 |
5 | import * as C from './Concat.js'
6 |
7 | describe(import.meta.url, () => {
8 | describe('First', () => {
9 | it('is a Concat instance that always returns the first value', () => {
10 | deepStrictEqual(C.First.concat(1, 2), 1)
11 | })
12 | })
13 | describe('Second', () => {
14 | it('is a Concat instance that always returns the second value', () => {
15 | deepStrictEqual(C.Second.concat(1, 2), 2)
16 | })
17 | })
18 |
19 | describe('concatAll', () => {
20 | it('uses a Concat instance to concatenate multiple values', () => {
21 | deepStrictEqual(C.concatAll({ concat: (x: number, y) => x + y })(0)([1, 2, 3, 4, 5]), 15)
22 | })
23 | })
24 |
25 | describe('reverse', () => {
26 | it('uses a Concat instance to concatenate multiple values', () => {
27 | deepStrictEqual(C.reverse(C.First).concat(1, 2), 2)
28 | deepStrictEqual(C.reverse(C.Second).concat(1, 2), 1)
29 | })
30 | })
31 |
32 | describe('fromLazy', () => {
33 | it('uses a Concat instance that always returns the lazily applied function', () => {
34 | deepStrictEqual(C.fromLazy(() => 3).concat(1, 2), 3)
35 | })
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/ForEach.separated.ts:
--------------------------------------------------------------------------------
1 | import { HKTParam, Kind, Static, Tuple } from '../AST.js'
2 |
3 | import { Covariant } from './Covariant.js'
4 | import { ForEach } from './ForEach.js'
5 | import { IdentityBoth } from './IdentityBoth.js'
6 | import { Separate } from './Separate.js'
7 | import {
8 | aTypeParam,
9 | bTypeParam,
10 | cTypeParam,
11 | derived_,
12 | fnLabeled_,
13 | fn_,
14 | kind_,
15 | placeholder,
16 | } from './common.js'
17 |
18 | const hkt2 = new HKTParam(Symbol('T2'), 'T2')
19 |
20 | export const separated = derived_(
21 | 'separated',
22 | [ForEach, Separate],
23 | derived_(
24 | '',
25 | [IdentityBoth, Covariant],
26 | fn_(
27 | '',
28 | [aTypeParam,hkt2.toPlaceholder(), bTypeParam, cTypeParam],
29 | [
30 | fnLabeled_(
31 | 'f',
32 | [],
33 | [aTypeParam.labeled('a')],
34 | new Kind(hkt2, [hkt2.toPlaceholder(), new Static(`Either`)]),
35 | ),
36 | ],
37 | fn_(
38 | '',
39 | [placeholder],
40 | [kind_([aTypeParam]).labeled()],
41 | new Kind(hkt2, [
42 | hkt2.toPlaceholder(),
43 | new Tuple([kind_([bTypeParam]), kind_([cTypeParam])]),
44 | ]),
45 | ),
46 | ),
47 | hkt2,
48 | ),
49 | )
50 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Law/testCovariantIdentityFlatten.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, IntersectionNode, ObjectNode, Static } from '../../AST.js'
2 | import { Covariant } from '../Covariant.js'
3 | import { IdentityFlatten } from '../IdentityFlatten.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | cTypeParam,
8 | curriedPlaceholder_,
9 | fnLabeled_,
10 | fn_,
11 | hkt,
12 | kind_,
13 | placeholder,
14 | } from '../common.js'
15 |
16 | export const testCovariantIdentityFlatten = fn_(
17 | 'testCovariantIdentityFlatten',
18 | [hkt, curriedPlaceholder_(hkt), placeholder, aTypeParam, bTypeParam, cTypeParam],
19 | [
20 | new IntersectionNode(Covariant.toTypeClass(hkt), IdentityFlatten.toTypeClass(hkt)).labeled(
21 | 'AFC',
22 | ),
23 | fnLabeled_('f', [], [aTypeParam.labeled('a')], kind_([bTypeParam])),
24 | new Dynamic([kind_([cTypeParam])], ([k]) => `Eq<${k}>`).labeled('E'),
25 | ],
26 | fn_(
27 | '',
28 | [],
29 | [new Static(`Arbitrary.Arbitrary`).labeled('A')],
30 | fn_(
31 | '',
32 | [],
33 | [new Static(`typeof import('fast-check')`).labeled('fc')],
34 | new ObjectNode([
35 | new Static(`() => void`).labeled('leftIdentity'),
36 | new Static(`() => void`).labeled('rightIdentity'),
37 | ]),
38 | ),
39 | ),
40 | )
41 |
--------------------------------------------------------------------------------
/src/Typeclass/ForEach/ForEach.test.ts:
--------------------------------------------------------------------------------
1 | import { deepStrictEqual } from 'node:assert'
2 |
3 | import { describe, it } from 'vitest'
4 |
5 | import * as Array from '../../Array.js'
6 | import * as Data from '../../Data.js'
7 | import * as Either from '../../Either.js'
8 | import { pipe } from '../../function.js'
9 | import * as N from '../../number.js'
10 |
11 | import * as ForEach from './index.js'
12 |
13 | describe(import.meta.url, () => {
14 | describe(ForEach.foldMap.name, () => {
15 | it('derives foldMap from ForEach instance', () => {
16 | const foldMapArray = ForEach.foldMap(Array.ForEach)(N.IdentitySum)
17 | const foldMapData = ForEach.foldMap(Data.ForEach)(N.IdentitySum)
18 | const foldMapEither = ForEach.foldMap(Either.ForEach)(N.IdentitySum)
19 |
20 | deepStrictEqual(
21 | pipe(
22 | [1, 2, 3],
23 | foldMapArray((x: number) => x + 1),
24 | ),
25 | 9,
26 | )
27 |
28 | deepStrictEqual(
29 | pipe(
30 | Data.Replete(1),
31 | foldMapData((x: number) => x + 1),
32 | ),
33 | 2,
34 | )
35 |
36 | deepStrictEqual(
37 | pipe(
38 | Either.Right(1),
39 | foldMapEither((a: number) => a + 1),
40 | ),
41 | 2,
42 | )
43 | })
44 | })
45 | })
46 |
--------------------------------------------------------------------------------
/src/struct.ts:
--------------------------------------------------------------------------------
1 | import { Cast } from 'ts-toolbelt/out/Any/Cast.js'
2 |
3 | import { Associative } from './Typeclass/Associative.js'
4 | import { Identity } from './Typeclass/Identity.js'
5 |
6 | export type StructEntries = ReadonlyArray
7 |
8 | export const fromEntries = (
9 | ...entries: Entries
10 | ): FromEntries => Object.fromEntries(entries) as FromEntries
11 |
12 | export type FromEntries = Entries extends readonly [
13 | readonly [infer K, infer V],
14 | ...infer Rest,
15 | ]
16 | ? FromEntries, Intersect, V>>>
17 | : { readonly [K in keyof R]: R[K] }
18 |
19 | export type KV = {
20 | readonly [_ in K]: V
21 | }
22 |
23 | export type Intersect = {
24 | readonly [K in keyof A | keyof B]: K extends keyof B ? B[K] : A[Cast]
25 | }
26 |
27 | export const makeAssignAssociative = (): Associative => ({
28 | concat: (first, second) => ({ ...first, ...second }),
29 | })
30 |
31 | export const empty: Readonly> = Object.create(null)
32 |
33 | export const makeAssignIdentity = (): Identity => ({
34 | ...makeAssignAssociative(),
35 | id: empty,
36 | })
37 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Law/testCovariantIdentityBoth.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, IntersectionNode, ObjectNode, Static } from '../../AST.js'
2 | import { Covariant } from '../Covariant.js'
3 | import { IdentityBoth } from '../IdentityBoth.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | curriedPlaceholder_,
8 | fnLabeled_,
9 | fn_,
10 | hkt,
11 | kind_,
12 | placeholder,
13 | } from '../common.js'
14 |
15 | export const testCovariantIdentityBoth = fn_(
16 | 'testCovariantIdentityBoth',
17 | [hkt, curriedPlaceholder_(hkt), placeholder, aTypeParam, bTypeParam],
18 | [
19 | new IntersectionNode(Covariant.toTypeClass(hkt), IdentityBoth.toTypeClass(hkt)).labeled('IBC'),
20 | new Dynamic([kind_([aTypeParam])], ([k]) => `Eq<${k}>`).labeled('EA'),
21 | fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam),
22 | new Dynamic([kind_([bTypeParam])], ([k]) => `Eq<${k}>`).labeled('EB'),
23 | ],
24 | fn_(
25 | '',
26 | [],
27 | [new Static(`Arbitrary.Arbitrary`).labeled('A')],
28 | fn_(
29 | '',
30 | [],
31 | [new Static(`typeof import('fast-check')`).labeled('fc')],
32 | new ObjectNode([
33 | new Static(`() => void`).labeled('identity'),
34 | new Static(`() => void`).labeled('homomorphism'),
35 | new Static(`() => void`).labeled('interchange'),
36 | ]),
37 | ),
38 | ),
39 | )
40 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Law/testCovariantAssociativeEither.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, IntersectionNode, ObjectNode, Static } from '../../AST.js'
2 | import { AssociativeEither } from '../AssociativeEither.js'
3 | import { Covariant } from '../Covariant.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | curriedPlaceholder_,
8 | fnLabeled_,
9 | fn_,
10 | hkt,
11 | kind_,
12 | placeholder,
13 | } from '../common.js'
14 |
15 | export const testCovariantAssociativeEither = fn_(
16 | 'testCovariantAssociativeEither',
17 | [hkt, curriedPlaceholder_(hkt), placeholder, aTypeParam, bTypeParam],
18 | [
19 | new IntersectionNode(Covariant.toTypeClass(hkt), AssociativeEither.toTypeClass(hkt)).labeled(
20 | 'IBC',
21 | ),
22 | new Dynamic([kind_([aTypeParam])], ([k]) => `Eq<${k}>`).labeled('EA'),
23 | fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam),
24 | new Dynamic([kind_([bTypeParam])], ([k]) => `Eq<${k}>`).labeled('EB'),
25 | ],
26 | fn_(
27 | '',
28 | [],
29 | [new Dynamic([kind_([aTypeParam])], ([k]) => `Arbitrary.Arbitrary<${k}>`).labeled('A')],
30 | fn_(
31 | '',
32 | [],
33 | [new Static(`typeof import('fast-check')`).labeled('fc')],
34 | new ObjectNode([
35 | new Static(`() => void`).labeled('associativity'),
36 | new Static(`() => void`).labeled('distributivity'),
37 | ]),
38 | ),
39 | ),
40 | )
41 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Law/testCovariantAssociativeFlatten.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, IntersectionNode, ObjectNode, Static } from '../../AST.js'
2 | import { AssociativeFlatten } from '../AssociativeFlatten.js'
3 | import { Covariant } from '../Covariant.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | cTypeParam,
8 | curriedPlaceholder_,
9 | fnLabeled_,
10 | fn_,
11 | hkt,
12 | kind_,
13 | placeholder,
14 | } from '../common.js'
15 |
16 | export const testCovariantAssociativeFlatten = fn_(
17 | 'testCovariantAssociativeFlatten',
18 | [hkt, curriedPlaceholder_(hkt), placeholder, aTypeParam, bTypeParam, cTypeParam],
19 | [
20 | new IntersectionNode(Covariant.toTypeClass(hkt), AssociativeFlatten.toTypeClass(hkt)).labeled(
21 | 'AFC',
22 | ),
23 | fnLabeled_('f', [], [aTypeParam.labeled('a')], kind_([bTypeParam])),
24 | fnLabeled_('g', [], [bTypeParam.labeled('b')], kind_([cTypeParam])),
25 | new Dynamic([kind_([bTypeParam])], ([k]) => `Eq<${k}>`).labeled('E'),
26 | ],
27 | fn_(
28 | '',
29 | [],
30 | [new Dynamic([kind_([aTypeParam])], ([k]) => `Arbitrary.Arbitrary<${k}>`).labeled('A')],
31 | fn_(
32 | '',
33 | [],
34 | [new Static(`typeof import('fast-check')`).labeled('fc')],
35 | new ObjectNode([
36 | new Static(`() => void`).labeled('associativity'),
37 | new Static(`() => void`).labeled('derivedAssociativeBoth'),
38 | ]),
39 | ),
40 | ),
41 | )
42 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Law/testCovariantIdentityEither.ts:
--------------------------------------------------------------------------------
1 | import { Dynamic, IntersectionNode, ObjectNode, Static } from '../../AST.js'
2 | import { Covariant } from '../Covariant.js'
3 | import { IdentityEither } from '../IdentityEither.js'
4 | import {
5 | aTypeParam,
6 | bTypeParam,
7 | curriedPlaceholder_,
8 | fnLabeled_,
9 | fn_,
10 | hkt,
11 | kind_,
12 | placeholder,
13 | } from '../common.js'
14 |
15 | export const testCovariantIdentityEither = fn_(
16 | 'testCovariantIdentityEither',
17 | [hkt, curriedPlaceholder_(hkt), placeholder, aTypeParam, bTypeParam],
18 | [
19 | new IntersectionNode(Covariant.toTypeClass(hkt), IdentityEither.toTypeClass(hkt)).labeled(
20 | 'IBC',
21 | ),
22 | new Dynamic([kind_([aTypeParam])], ([k]) => `Eq<${k}>`).labeled('EA'),
23 | fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam),
24 | new Dynamic([kind_([bTypeParam])], ([k]) => `Eq<${k}>`).labeled('EB'),
25 | ],
26 | fn_(
27 | '',
28 | [],
29 | [new Dynamic([kind_([aTypeParam])], ([k]) => `Arbitrary.Arbitrary<${k}>`).labeled('A')],
30 | fn_(
31 | '',
32 | [],
33 | [new Static(`typeof import('fast-check')`).labeled('fc')],
34 | new ObjectNode([
35 | new Static(`() => void`).labeled('distributivity'),
36 | new Static(`() => void`).labeled('leftIdentity'),
37 | new Static(`() => void`).labeled('rightIdentity'),
38 | new Static(`() => void`).labeled('annihilation'),
39 | ]),
40 | ),
41 | ),
42 | )
43 |
--------------------------------------------------------------------------------
/src/Typeclass/Inverse.test.ts:
--------------------------------------------------------------------------------
1 | import { deepStrictEqual } from 'node:assert'
2 |
3 | import { describe, it } from 'vitest'
4 |
5 | import { InverseAll, InverseAny } from '../boolean.js'
6 | import { Inverse } from '../number.js'
7 |
8 | import { multiply } from './Inverse.js'
9 |
10 | describe(import.meta.url, () => {
11 | describe(multiply.name, () => {
12 | it('allows multiplying a value', () => {
13 | deepStrictEqual(multiply(Inverse)(2, 2), 4)
14 | deepStrictEqual(multiply(Inverse)(2, -2), -4)
15 |
16 | deepStrictEqual(multiply(InverseAll)(true, 2), true, 'InverseAll :: true * 2 = true')
17 | deepStrictEqual(multiply(InverseAll)(true, -1), false, 'InverseAll :: true * -1 = false')
18 | deepStrictEqual(multiply(InverseAll)(false, 2), false, 'InverseAll :: false * 2 = false')
19 | deepStrictEqual(multiply(InverseAll)(false, 1), false, 'InverseAll :: false * 1 = false')
20 | deepStrictEqual(multiply(InverseAll)(false, -1), true, 'InverseAll :: false * -1 = true')
21 |
22 | deepStrictEqual(multiply(InverseAny)(true, 2), true, 'InverseAny :: true * 2 = true')
23 | deepStrictEqual(multiply(InverseAny)(true, -1), false, 'InverseAny :: true * -1 = false')
24 | deepStrictEqual(multiply(InverseAny)(false, 2), false, 'InverseAny :: false * 2 = false')
25 | deepStrictEqual(multiply(InverseAny)(false, 1), false, 'InverseAny :: false * 1 = false')
26 | deepStrictEqual(multiply(InverseAny)(false, -1), true, 'InverseAny :: false * -1 = true')
27 | })
28 | })
29 | })
30 |
--------------------------------------------------------------------------------
/tools/overloads/definitions/Law/testContravariant.ts:
--------------------------------------------------------------------------------
1 | import { ObjectNode, Static } from '../../AST.js'
2 | import { Contravariant } from '../Contravariant.js'
3 | import {
4 | aTypeParam,
5 | bTypeParam,
6 | cTypeParam,
7 | curriedPlaceholder_,
8 | dTypeParam,
9 | fnLabeled_,
10 | fn_,
11 | hkt,
12 | kind_,
13 | placeholder,
14 | } from '../common.js'
15 |
16 | export const testContravariant = fn_(
17 | 'testContravariant',
18 | [hkt, curriedPlaceholder_(hkt), aTypeParam, bTypeParam, cTypeParam, placeholder, dTypeParam],
19 | [
20 | Contravariant.toTypeClass(hkt).labeled('C'),
21 | fnLabeled_('f', [], [aTypeParam.labeled('a')], bTypeParam),
22 | fnLabeled_('g', [], [bTypeParam.labeled('b')], cTypeParam),
23 | kind_([aTypeParam]).labeled('kindA'),
24 | kind_([cTypeParam]).labeled('kindC'),
25 | fnLabeled_(
26 | 'run',
27 | [aTypeParam],
28 | [
29 | kind_([aTypeParam]).labeled(),
30 | aTypeParam.labeled('a'),
31 | aTypeParam.labeled('b'),
32 | aTypeParam.labeled('c'),
33 | ],
34 | dTypeParam,
35 | ),
36 | new Static(`Eq`).labeled(`Eq?`),
37 | ],
38 | fn_(
39 | '',
40 | [],
41 | [new Static(`Arbitrary.Arbitrary`).labeled('AA')],
42 | fn_(
43 | '',
44 | [],
45 | [new Static(`typeof import('fast-check')`).labeled('fc')],
46 | new ObjectNode([
47 | new Static(`() => void`).labeled('identity'),
48 | new Static(`() => void`).labeled('associativity'),
49 | ]),
50 | ),
51 | ),
52 | )
53 |
--------------------------------------------------------------------------------
/src/Typeclass/index.ts:
--------------------------------------------------------------------------------
1 | export * as Associative from './Associative.js'
2 | export * as AssociativeBoth from './AssociativeBoth.js'
3 | export * as AssociativeCompose from './AssociativeCompose.js'
4 | export * as AssociativeEither from './AssociativeEither.js'
5 | export * as AssociativeFlatten from './AssociativeFlatten.js'
6 | export * as Bicovariant from './Bicovariant.js'
7 | export * as Bottom from './Bottom.js'
8 | export * as Bounded from './Bounded.js'
9 | export * as Commutative from './Commutative.js'
10 | export * as CommutativeBoth from './CommutativeBoth.js'
11 | export * as CommutativeEither from './CommutativeEither.js'
12 | export * as Compact from './Compact.js'
13 | export * as Compactable from './Compactable.js'
14 | export * as Concat from './Concat.js'
15 | export * as Contravariant from './Contravariant.js'
16 | export * as Covariant from './Covariant.js'
17 | export * as CovariantWithIndex from './CovariantWithIndex.js'
18 | export * as Debug from './Debug.js'
19 | export * as Divariant from './Divariant.js'
20 | export * as ForEach from './ForEach/index.js'
21 | export * as IdentityBoth from './IdentityBoth.js'
22 | export * as IdentityEither from './IdentityEither.js'
23 | export * as IdentityFlatten from './IdentityFlatten.js'
24 | export * as Invariant from './Invariant.js'
25 | export * as Inverse from './Inverse.js'
26 | export * as NaturalTransformation from './NaturalTransformation.js'
27 | export * as Ord from './Ord.js'
28 | export * as Separate from './Separate.js'
29 | export * as Top from './Top.js'
30 | export * as Trivariant from './Trivariant.js'
31 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | # Javascript Node CircleCI 2.0 configuration file
2 | #
3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details
4 | #
5 | version: 2.1
6 |
7 | executors:
8 | lts:
9 | docker:
10 | - image: cimg/node:lts
11 |
12 | working_directory: ~/repo
13 | resource_class: large
14 |
15 | latest:
16 | docker:
17 | - image: cimg/node:current
18 |
19 | working_directory: ~/repo
20 | resource_class: large
21 |
22 | jobs:
23 | test-lts:
24 | executor: lts
25 | steps:
26 | - checkout
27 |
28 | - restore_cache:
29 | keys:
30 | - v1-dependencies-{{ checksum "pnpm-lock.yaml" }}
31 |
32 | - run: corepack enable
33 | - run: pnpm add -g pnpm
34 | - run: pnpm install
35 |
36 | - save_cache:
37 | paths:
38 | - node_modules
39 | key: v1-dependencies-{{ checksum "pnpm-lock.yaml" }}
40 |
41 | - run: npm run test
42 |
43 | test-latest:
44 | executor: latest
45 | steps:
46 | - checkout
47 |
48 | - restore_cache:
49 | keys:
50 | - v1-dependencies-{{ checksum "pnpm-lock.yaml" }}
51 |
52 | - run: corepack enable
53 | - run: pnpm add -g pnpm
54 | - run: pnpm install
55 |
56 | - save_cache:
57 | paths:
58 | - node_modules
59 | key: v1-dependencies-{{ checksum "pnpm-lock.yaml" }}
60 |
61 | - run: npm run test
62 |
63 | workflows:
64 | version: 2
65 | test-node:
66 | jobs:
67 | - test-lts
68 | - test-latest
69 |
--------------------------------------------------------------------------------
/src/Law/Ord.ts:
--------------------------------------------------------------------------------
1 | import { Ord } from '../Typeclass/Ord.js'
2 | import { pipe } from '../function.js'
3 |
4 | import * as Arbitrary from './Arbitrary.js'
5 |
6 | export function testOrd(O: Ord) {
7 | return (Arb: Arbitrary.Arbitrary) => (fc: typeof import('fast-check')) => ({
8 | totality: () => testOrdTotality(O)(Arb).property(fc),
9 | reflexivity: () => testOrdReflexivity(O)(Arb).property(fc),
10 | antisymmetry: () => testOrdAntisymmetry(O)(Arb).property(fc),
11 | transitivity: () => testOrdTransitivity(O)(Arb).property(fc),
12 | })
13 | }
14 |
15 | export function testOrdTotality(O: Ord) {
16 | return (Arb: Arbitrary.Arbitrary) =>
17 | pipe(
18 | Arbitrary.tuple(Arb, Arb),
19 | Arbitrary.toProperty(([a, b]) => O.compare(a, b) <= 0 || O.compare(b, a) <= 0),
20 | )
21 | }
22 |
23 | export function testOrdReflexivity(O: Ord) {
24 | return (Arb: Arbitrary.Arbitrary) =>
25 | pipe(
26 | Arb,
27 | Arbitrary.toProperty((a) => O.compare(a, a) <= 0),
28 | )
29 | }
30 |
31 | export function testOrdAntisymmetry(O: Ord) {
32 | return (Arb: Arbitrary.Arbitrary) =>
33 | pipe(
34 | Arbitrary.tuple(Arb, Arb),
35 | Arbitrary.toProperty(
36 | ([a, b]) => (O.compare(a, b) <= 0 && O.compare(b, a) <= 0) === O.equals(a, b),
37 | ),
38 | )
39 | }
40 |
41 | export function testOrdTransitivity(O: Ord) {
42 | return (Arb: Arbitrary.Arbitrary) =>
43 | pipe(
44 | Arbitrary.tuple(Arb, Arb, Arb),
45 | Arbitrary.toProperty(
46 | ([a, b, c]) => !(O.compare(a, b) <= 0 && O.compare(b, c) <= 0) || O.compare(a, c) <= 0,
47 | ),
48 | )
49 | }
50 |
--------------------------------------------------------------------------------
/tools/common.ts:
--------------------------------------------------------------------------------
1 | import { readFileSync, readdirSync } from 'node:fs'
2 | import { dirname, isAbsolute, join } from 'node:path'
3 |
4 | import fastGlob from 'fast-glob'
5 |
6 | export const ROOT_DIR = dirname(dirname(new URL(import.meta.url).pathname))
7 | export const SOURCE_DIR = join(ROOT_DIR, 'src')
8 |
9 | export const ROOT_FILES = ['exports']
10 |
11 | export function compiledFiles(name: string): readonly string[] {
12 | const fileName = parseName(name)
13 |
14 | return [`/${fileName}.d.ts`, `/${fileName}.d.ts.map`, `/${fileName}.js`, `/${fileName}.js.map`]
15 | }
16 |
17 | export function parseName(name: string): string {
18 | return name.replace(/\.tsx?/, '')
19 | }
20 |
21 | export const MODULES: ReadonlyArray = readdirSync(SOURCE_DIR)
22 | .sort()
23 | .filter(
24 | (x) => x !== 'internal.ts' && x !== 'index.ts' && !x.endsWith('.test.ts') && !x.startsWith('.'),
25 | )
26 |
27 | export function getRelativeFile(directory: string, fileName: string) {
28 | return join(directory, fileName)
29 | }
30 |
31 | export function readRelativeFile(directory: string, fileName: string) {
32 | return readFileSync(getRelativeFile(directory, fileName)).toString()
33 | }
34 |
35 | export function findFilePaths(directory: string, fileGlobs: readonly string[]): string[] {
36 | // eslint-disable-next-line import/no-named-as-default-member
37 | return fastGlob
38 | .sync(Array.from(fileGlobs), { cwd: directory, onlyFiles: true })
39 | .map((x) => makeAbsolute(directory, x.toString()))
40 | }
41 |
42 | export function makeAbsolute(basePath: string, absoluteOrRelative: string): string {
43 | return isAbsolute(absoluteOrRelative) ? absoluteOrRelative : join(basePath, absoluteOrRelative)
44 | }
45 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: '@typescript-eslint/parser',
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:@typescript-eslint/eslint-recommended',
7 | 'plugin:@typescript-eslint/recommended',
8 | 'prettier',
9 | 'plugin:prettier/recommended',
10 | 'plugin:import/errors',
11 | 'plugin:import/warnings',
12 | 'plugin:import/typescript',
13 | ],
14 | ignorePatterns: ['docs/**'],
15 | parserOptions: {
16 | ecmaVersion: 2018,
17 | sourceType: 'module',
18 | },
19 | env: {
20 | node: true,
21 | },
22 | rules: {
23 | '@typescript-eslint/no-empty-interface': 'off',
24 | '@typescript-eslint/no-explicit-any': 'off',
25 | '@typescript-eslint/no-use-before-define': 'off',
26 | 'import/order': [
27 | 'error',
28 | {
29 | 'newlines-between': 'always',
30 | alphabetize: {
31 | order: 'asc',
32 | caseInsensitive: false,
33 | },
34 | },
35 | ],
36 | // Enable sort-imports to sort named imports within a single import
37 | // statement, but *disable* its declaration sort, and let
38 | // import/order's alphabetize feature handle sorting declarations
39 | // based on import path.
40 | 'sort-imports': [
41 | 'error',
42 | {
43 | ignoreDeclarationSort: true,
44 | },
45 | ],
46 | 'import/no-unresolved': 'off', // Allow TS to do this checking,
47 | 'import/no-cycle': ['error', { maxDepth: Infinity }],
48 | },
49 | settings: {
50 | 'import/parsers': {
51 | '@typescript-eslint/parser': ['.ts', '.tsx'],
52 | },
53 | 'import/resolver': {
54 | typescript: {
55 | project: '.',
56 | },
57 | },
58 | },
59 | }
60 |
--------------------------------------------------------------------------------
/src/Predicate.test.ts:
--------------------------------------------------------------------------------
1 | import * as fc from 'fast-check'
2 | import { describe, it } from 'vitest'
3 |
4 | import * as L from './Law/index.js'
5 | import { testAllDataLaws } from './Law/internal-test-all-laws.js'
6 | import * as P from './Predicate.js'
7 | import { fromEquals } from './Typeclass/Eq.js'
8 | import { pipe } from './function.js'
9 |
10 | describe(import.meta.url, () => {
11 | testAllDataLaws({
12 | name: `Predicate`,
13 | fc,
14 | Arbitrary: pipe(
15 | L.boolean,
16 | L.flatMap((b) => L.constant(() => b)),
17 | ),
18 | Associative: {
19 | All: [
20 | P.makeAssociativeAll(),
21 | fromEquals((f: P.Predicate, s) => f(1) === s(1) && f(2) === s(2)),
22 | ],
23 | Any: [
24 | P.makeAssociativeAny(),
25 | fromEquals((f: P.Predicate, s) => f(1) === s(1) && f(2) === s(2)),
26 | ],
27 | },
28 | Identity: {
29 | All: [
30 | P.makeIdentityAll(),
31 | fromEquals((f: P.Predicate, s) => f(1) === s(1) && f(2) === s(2)),
32 | ],
33 | Any: [
34 | P.makeIdentityAny(),
35 | fromEquals((f: P.Predicate, s) => f(1) === s(1) && f(2) === s(2)),
36 | ],
37 | },
38 | })
39 |
40 | describe('Contravariant', () => {
41 | const { identity, associativity } = L.Contravariant.testContravariant()(
42 | P.Contravariant,
43 | (s: string) => s.length,
44 | (n: number) => n + 2,
45 | (a: string) => a.length % 2 === 0,
46 | (a: number) => a % 2 === 0,
47 | (predicate, n) => predicate(n),
48 | )(L.string())(fc)
49 |
50 | it('Identity', identity)
51 | it('Associativity', associativity)
52 | })
53 | })
54 |
--------------------------------------------------------------------------------
/src/Progress.ts:
--------------------------------------------------------------------------------
1 | import * as M from './Maybe.js'
2 | import * as A from './Typeclass/Associative.js'
3 | import * as C from './Typeclass/Commutative.js'
4 | import * as D from './Typeclass/Debug.js'
5 | import * as EQ from './Typeclass/Eq.js'
6 | import * as I from './Typeclass/Identity.js'
7 | import * as O from './Typeclass/Ord.js'
8 | import { pipe } from './function.js'
9 | import * as N from './number.js'
10 |
11 | export interface Progress {
12 | readonly loaded: N.NonNegativeFloat
13 | readonly total: M.Maybe
14 | }
15 |
16 | export function Progress(
17 | loaded: N.NonNegativeFloat,
18 | total: M.Maybe = M.Nothing,
19 | ): Progress {
20 | return {
21 | loaded,
22 | total,
23 | }
24 | }
25 |
26 | export const Associative: A.Associative