From 093c3966a40b95823c57c09d88b766437b96f6c7 Mon Sep 17 00:00:00 2001 From: hfutsora <346762712@qq.com> Date: Tue, 5 Jul 2022 18:21:51 +0800 Subject: [PATCH] feat: functor definitions --- package.json | 1 + pnpm-lock.yaml | 194 +++++++++++++++++++++++----------- src/Functors/Alt.ts | 24 +++++ src/Functors/Alternative.ts | 16 +++ src/Functors/Applicative.ts | 24 +++++ src/Functors/Apply.ts | 22 ++++ src/Functors/Bifunctor.ts | 15 +++ src/Functors/Category.ts | 22 ++++ src/Functors/Chain.ts | 22 ++++ src/Functors/ChainRec.ts | 24 +++++ src/Functors/Comonad.ts | 23 ++++ src/Functors/Contravariant.ts | 22 ++++ src/Functors/Extend.ts | 22 ++++ src/Functors/Filterable.ts | 24 +++++ src/Functors/Foldable.ts | 21 ++++ src/Functors/Functor.ts | 30 ++---- src/Functors/Group.ts | 23 ++++ src/Functors/Monad.ts | 16 +++ src/Functors/Monoid.ts | 23 ++++ src/Functors/Ord.ts | 24 +++++ src/Functors/Plus.ts | 24 +++++ src/Functors/Profunctor.ts | 16 +++ src/Functors/Semigroup.ts | 22 ++++ src/Functors/Semigroupoid.ts | 21 ++++ src/Functors/Setoid.ts | 23 ++++ src/Functors/Traversable.ts | 28 +++++ 26 files changed, 644 insertions(+), 82 deletions(-) create mode 100644 src/Functors/Filterable.ts diff --git a/package.json b/package.json index 75ffd1b..110e1b7 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "@rollup/plugin-typescript": "^8.2.1", "@types/jest": "^26.0.19", "@types/lodash-es": "^4.17.5", + "@types/node": "^18.0.1", "@typescript-eslint/eslint-plugin": "^5.24.0", "@typescript-eslint/parser": "^5.24.0", "babel-plugin-add-import-extension": "^1.5.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a22700..def188a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,10 +8,11 @@ specifiers: '@babel/plugin-transform-modules-umd': ^7.14.5 '@babel/plugin-transform-runtime': ^7.14.5 '@babel/preset-env': ^7.14.7 - '@commitlint/config-conventional': ^15.0.0 + '@commitlint/config-conventional': ^17.0.3 '@rollup/plugin-typescript': ^8.2.1 '@types/jest': ^26.0.19 '@types/lodash-es': ^4.17.5 + '@types/node': ^18.0.1 '@typescript-eslint/eslint-plugin': ^5.24.0 '@typescript-eslint/parser': ^5.24.0 babel-plugin-add-import-extension: ^1.5.1 @@ -19,14 +20,14 @@ specifiers: commitlint: ^15.0.0 darl: ^2.1.1 eslint: ^8.15.0 - husky: ^7.0.4 + husky: ^8.0.1 jest: ^26.6.3 ncp: ^2.0.0 rollup: ^2.35.1 rollup-plugin-node-resolve: ^5.2.0 rollup-plugin-terser: ^7.0.2 ts-jest: ^26.4.4 - ts-node: ^9.1.1 + ts-node: ^10.8.2 tslib: ^2.0.3 typescript: ^4.1.3 @@ -41,10 +42,11 @@ devDependencies: '@babel/plugin-transform-modules-umd': 7.17.12_@babel+core@7.17.12 '@babel/plugin-transform-runtime': 7.17.12_@babel+core@7.17.12 '@babel/preset-env': 7.17.12_@babel+core@7.17.12 - '@commitlint/config-conventional': 15.0.0 + '@commitlint/config-conventional': 17.0.3 '@rollup/plugin-typescript': 8.3.2_qvmxwb53ll4ofwdq3bekbs74hi '@types/jest': 26.0.24 '@types/lodash-es': 4.17.6 + '@types/node': 18.0.1 '@typescript-eslint/eslint-plugin': 5.24.0_w4ec7awddsetq6k5phhi6huiuu '@typescript-eslint/parser': 5.24.0_hcfsmds2fshutdssjqluwm76uu babel-plugin-add-import-extension: 1.6.0_@babel+core@7.17.12 @@ -52,14 +54,14 @@ devDependencies: commitlint: 15.0.0 darl: 2.2.0 eslint: 8.15.0 - husky: 7.0.4 - jest: 26.6.3_ts-node@9.1.1 + husky: 8.0.1 + jest: 26.6.3_ts-node@10.8.2 ncp: 2.0.0 rollup: 2.73.0 rollup-plugin-node-resolve: 5.2.0_rollup@2.73.0 rollup-plugin-terser: 7.0.2_rollup@2.73.0 ts-jest: 26.5.6_ip4jai7pxkumsngma2fb7ud2tm - ts-node: 9.1.1_typescript@4.6.4 + ts-node: 10.8.2_34czju737xwuz7ql7o6is73jii typescript: 4.6.4 packages: @@ -1276,11 +1278,11 @@ packages: yargs: 17.5.1 dev: true - /@commitlint/config-conventional/15.0.0: - resolution: {integrity: sha512-eZBRL8Lk3hMNHp1wUMYj0qrZQEsST1ai7KHR8J1IDD9aHgT7L2giciibuQ+Og7vxVhR5WtYDvh9xirXFVPaSkQ==} - engines: {node: '>=v12'} + /@commitlint/config-conventional/17.0.3: + resolution: {integrity: sha512-HCnzTm5ATwwwzNVq5Y57poS0a1oOOcd5pc1MmBpLbGmSysc4i7F/++JuwtdFPu16sgM3H9J/j2zznRLOSGVO2A==} + engines: {node: '>=v14'} dependencies: - conventional-changelog-conventionalcommits: 4.6.3 + conventional-changelog-conventionalcommits: 5.0.0 dev: true /@commitlint/ensure/15.0.0: @@ -1401,6 +1403,13 @@ packages: chalk: 4.1.2 dev: true + /@cspotcode/source-map-support/0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + /@endemolshinegroup/cosmiconfig-typescript-loader/3.0.2_eqevhppa7sa2qvpxws2sflyfju: resolution: {integrity: sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==} engines: {node: '>=10.0.0'} @@ -1469,14 +1478,14 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 chalk: 4.1.2 jest-message-util: 26.6.2 jest-util: 26.6.2 slash: 3.0.0 dev: true - /@jest/core/26.6.3_ts-node@9.1.1: + /@jest/core/26.6.3_ts-node@10.8.2: resolution: {integrity: sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==} engines: {node: '>= 10.14.2'} dependencies: @@ -1485,20 +1494,20 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 ansi-escapes: 4.3.2 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 26.6.2 - jest-config: 26.6.3_ts-node@9.1.1 + jest-config: 26.6.3_ts-node@10.8.2 jest-haste-map: 26.6.2 jest-message-util: 26.6.2 jest-regex-util: 26.0.0 jest-resolve: 26.6.2 jest-resolve-dependencies: 26.6.3 - jest-runner: 26.6.3_ts-node@9.1.1 - jest-runtime: 26.6.3_ts-node@9.1.1 + jest-runner: 26.6.3_ts-node@10.8.2 + jest-runtime: 26.6.3_ts-node@10.8.2 jest-snapshot: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 @@ -1522,7 +1531,7 @@ packages: dependencies: '@jest/fake-timers': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 jest-mock: 26.6.2 dev: true @@ -1532,7 +1541,7 @@ packages: dependencies: '@jest/types': 26.6.2 '@sinonjs/fake-timers': 6.0.1 - '@types/node': 17.0.34 + '@types/node': 18.0.1 jest-message-util: 26.6.2 jest-mock: 26.6.2 jest-util: 26.6.2 @@ -1600,15 +1609,15 @@ packages: collect-v8-coverage: 1.0.1 dev: true - /@jest/test-sequencer/26.6.3_ts-node@9.1.1: + /@jest/test-sequencer/26.6.3_ts-node@10.8.2: resolution: {integrity: sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==} engines: {node: '>= 10.14.2'} dependencies: '@jest/test-result': 26.6.2 graceful-fs: 4.2.10 jest-haste-map: 26.6.2 - jest-runner: 26.6.3_ts-node@9.1.1 - jest-runtime: 26.6.3_ts-node@9.1.1 + jest-runner: 26.6.3_ts-node@10.8.2 + jest-runtime: 26.6.3_ts-node@10.8.2 transitivePeerDependencies: - bufferutil - canvas @@ -1646,7 +1655,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 17.0.34 + '@types/node': 18.0.1 '@types/yargs': 15.0.14 chalk: 4.1.2 dev: true @@ -1689,6 +1698,13 @@ packages: '@jridgewell/sourcemap-codec': 1.4.13 dev: true + /@jridgewell/trace-mapping/0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.0.7 + '@jridgewell/sourcemap-codec': 1.4.13 + dev: true + /@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3: resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} requiresBuild: true @@ -1760,6 +1776,22 @@ packages: engines: {node: '>= 6'} dev: true + /@tsconfig/node10/1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12/1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14/1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16/1.0.3: + resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} + dev: true + /@types/babel__core/7.1.19: resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} dependencies: @@ -1796,7 +1828,7 @@ packages: /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 17.0.34 + '@types/node': 18.0.1 dev: true /@types/istanbul-lib-coverage/2.0.4: @@ -1840,8 +1872,8 @@ packages: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true - /@types/node/17.0.34: - resolution: {integrity: sha512-XImEz7XwTvDBtzlTnm8YvMqGW/ErMWBsKZ+hMTvnDIjGCKxwK5Xpc+c/oQjOauwq8M4OS11hEkpjX8rrI/eEgA==} + /@types/node/18.0.1: + resolution: {integrity: sha512-CmR8+Tsy95hhwtZBKJBs0/FFq4XX7sDZHlGGf+0q+BRZfMbOTkzkj0AFAuTyXbObDIoanaBBW0+KEW+m3N16Wg==} dev: true /@types/normalize-package-data/2.4.1: @@ -1859,7 +1891,7 @@ packages: /@types/resolve/0.0.8: resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} dependencies: - '@types/node': 17.0.34 + '@types/node': 18.0.1 dev: true /@types/stack-utils/2.0.1: @@ -2034,6 +2066,11 @@ packages: engines: {node: '>=0.4.0'} dev: true + /acorn-walk/8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + /acorn/7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} @@ -2629,8 +2666,8 @@ packages: q: 1.5.1 dev: true - /conventional-changelog-conventionalcommits/4.6.3: - resolution: {integrity: sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==} + /conventional-changelog-conventionalcommits/5.0.0: + resolution: {integrity: sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==} engines: {node: '>=10'} dependencies: compare-func: 2.0.0 @@ -3561,9 +3598,9 @@ packages: engines: {node: '>=10.17.0'} dev: true - /husky/7.0.4: - resolution: {integrity: sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==} - engines: {node: '>=12'} + /husky/8.0.1: + resolution: {integrity: sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==} + engines: {node: '>=14'} hasBin: true dev: true @@ -3901,12 +3938,12 @@ packages: throat: 5.0.0 dev: true - /jest-cli/26.6.3_ts-node@9.1.1: + /jest-cli/26.6.3_ts-node@10.8.2: resolution: {integrity: sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==} engines: {node: '>= 10.14.2'} hasBin: true dependencies: - '@jest/core': 26.6.3_ts-node@9.1.1 + '@jest/core': 26.6.3_ts-node@10.8.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 chalk: 4.1.2 @@ -3914,7 +3951,7 @@ packages: graceful-fs: 4.2.10 import-local: 3.1.0 is-ci: 2.0.0 - jest-config: 26.6.3_ts-node@9.1.1 + jest-config: 26.6.3_ts-node@10.8.2 jest-util: 26.6.2 jest-validate: 26.6.2 prompts: 2.4.2 @@ -3927,7 +3964,7 @@ packages: - utf-8-validate dev: true - /jest-config/26.6.3_ts-node@9.1.1: + /jest-config/26.6.3_ts-node@10.8.2: resolution: {integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==} engines: {node: '>= 10.14.2'} peerDependencies: @@ -3937,7 +3974,7 @@ packages: optional: true dependencies: '@babel/core': 7.17.12 - '@jest/test-sequencer': 26.6.3_ts-node@9.1.1 + '@jest/test-sequencer': 26.6.3_ts-node@10.8.2 '@jest/types': 26.6.2 babel-jest: 26.6.3_@babel+core@7.17.12 chalk: 4.1.2 @@ -3947,14 +3984,14 @@ packages: jest-environment-jsdom: 26.6.2 jest-environment-node: 26.6.2 jest-get-type: 26.3.0 - jest-jasmine2: 26.6.3_ts-node@9.1.1 + jest-jasmine2: 26.6.3_ts-node@10.8.2 jest-regex-util: 26.0.0 jest-resolve: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 micromatch: 4.0.5 pretty-format: 26.6.2 - ts-node: 9.1.1_typescript@4.6.4 + ts-node: 10.8.2_34czju737xwuz7ql7o6is73jii transitivePeerDependencies: - bufferutil - canvas @@ -3997,7 +4034,7 @@ packages: '@jest/environment': 26.6.2 '@jest/fake-timers': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 jest-mock: 26.6.2 jest-util: 26.6.2 jsdom: 16.7.0 @@ -4015,7 +4052,7 @@ packages: '@jest/environment': 26.6.2 '@jest/fake-timers': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 jest-mock: 26.6.2 jest-util: 26.6.2 dev: true @@ -4031,7 +4068,7 @@ packages: dependencies: '@jest/types': 26.6.2 '@types/graceful-fs': 4.1.5 - '@types/node': 17.0.34 + '@types/node': 18.0.1 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.10 @@ -4048,7 +4085,7 @@ packages: - supports-color dev: true - /jest-jasmine2/26.6.3_ts-node@9.1.1: + /jest-jasmine2/26.6.3_ts-node@10.8.2: resolution: {integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==} engines: {node: '>= 10.14.2'} dependencies: @@ -4057,7 +4094,7 @@ packages: '@jest/source-map': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 chalk: 4.1.2 co: 4.6.0 expect: 26.6.2 @@ -4065,7 +4102,7 @@ packages: jest-each: 26.6.2 jest-matcher-utils: 26.6.2 jest-message-util: 26.6.2 - jest-runtime: 26.6.3_ts-node@9.1.1 + jest-runtime: 26.6.3_ts-node@10.8.2 jest-snapshot: 26.6.2 jest-util: 26.6.2 pretty-format: 26.6.2 @@ -4116,7 +4153,7 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 dev: true /jest-pnp-resolver/1.2.2_jest-resolve@26.6.2: @@ -4161,7 +4198,7 @@ packages: slash: 3.0.0 dev: true - /jest-runner/26.6.3_ts-node@9.1.1: + /jest-runner/26.6.3_ts-node@10.8.2: resolution: {integrity: sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==} engines: {node: '>= 10.14.2'} dependencies: @@ -4169,18 +4206,18 @@ packages: '@jest/environment': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 chalk: 4.1.2 emittery: 0.7.2 exit: 0.1.2 graceful-fs: 4.2.10 - jest-config: 26.6.3_ts-node@9.1.1 + jest-config: 26.6.3_ts-node@10.8.2 jest-docblock: 26.0.0 jest-haste-map: 26.6.2 jest-leak-detector: 26.6.2 jest-message-util: 26.6.2 jest-resolve: 26.6.2 - jest-runtime: 26.6.3_ts-node@9.1.1 + jest-runtime: 26.6.3_ts-node@10.8.2 jest-util: 26.6.2 jest-worker: 26.6.2 source-map-support: 0.5.21 @@ -4193,7 +4230,7 @@ packages: - utf-8-validate dev: true - /jest-runtime/26.6.3_ts-node@9.1.1: + /jest-runtime/26.6.3_ts-node@10.8.2: resolution: {integrity: sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==} engines: {node: '>= 10.14.2'} hasBin: true @@ -4213,7 +4250,7 @@ packages: exit: 0.1.2 glob: 7.2.3 graceful-fs: 4.2.10 - jest-config: 26.6.3_ts-node@9.1.1 + jest-config: 26.6.3_ts-node@10.8.2 jest-haste-map: 26.6.2 jest-message-util: 26.6.2 jest-mock: 26.6.2 @@ -4237,7 +4274,7 @@ packages: resolution: {integrity: sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==} engines: {node: '>= 10.14.2'} dependencies: - '@types/node': 17.0.34 + '@types/node': 18.0.1 graceful-fs: 4.2.10 dev: true @@ -4270,7 +4307,7 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 chalk: 4.1.2 graceful-fs: 4.2.10 is-ci: 2.0.0 @@ -4295,7 +4332,7 @@ packages: dependencies: '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 17.0.34 + '@types/node': 18.0.1 ansi-escapes: 4.3.2 chalk: 4.1.2 jest-util: 26.6.2 @@ -4306,19 +4343,19 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 17.0.34 + '@types/node': 18.0.1 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true - /jest/26.6.3_ts-node@9.1.1: + /jest/26.6.3_ts-node@10.8.2: resolution: {integrity: sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==} engines: {node: '>= 10.14.2'} hasBin: true dependencies: - '@jest/core': 26.6.3_ts-node@9.1.1 + '@jest/core': 26.6.3_ts-node@10.8.2 import-local: 3.1.0 - jest-cli: 26.6.3_ts-node@9.1.1 + jest-cli: 26.6.3_ts-node@10.8.2 transitivePeerDependencies: - bufferutil - canvas @@ -5057,7 +5094,7 @@ packages: dev: true /q/1.5.1: - resolution: {integrity: sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=} + resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} engines: {node: '>=0.6.0', teleport: '>=0.2.0'} dev: true @@ -5829,7 +5866,7 @@ packages: bs-logger: 0.2.6 buffer-from: 1.1.2 fast-json-stable-stringify: 2.1.0 - jest: 26.6.3_ts-node@9.1.1 + jest: 26.6.3_ts-node@10.8.2 jest-util: 26.6.2 json5: 2.2.1 lodash: 4.17.21 @@ -5840,6 +5877,37 @@ packages: yargs-parser: 20.2.9 dev: true + /ts-node/10.8.2_34czju737xwuz7ql7o6is73jii: + resolution: {integrity: sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.3 + '@types/node': 18.0.1 + acorn: 8.7.1 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.6.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + /ts-node/9.1.1_typescript@4.6.4: resolution: {integrity: sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==} engines: {node: '>=10.0.0'} @@ -6011,6 +6079,10 @@ packages: hasBin: true dev: true + /v8-compile-cache-lib/3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + /v8-compile-cache/2.3.0: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true diff --git a/src/Functors/Alt.ts b/src/Functors/Alt.ts index e69de29..887cf6d 100644 --- a/src/Functors/Alt.ts +++ b/src/Functors/Alt.ts @@ -0,0 +1,24 @@ +/** + * Alt + * + * 1. a.alt(b).alt(c) is equivalent to a.alt(b.alt(c)) (associativity) + * 2. a.alt(b).map(f) is equivalent to a.map(f).alt(b.map(f)) (distributivity) + * + * alt :: Alt f => f a ~> f a -> f a + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Functor, Functor1, Functor2 } from './Functor' +import { Lazy } from '../function' + +export interface Alt extends Functor { + readonly alt: (fa: HKT, that: Lazy>) => HKT +} + +export interface Alt1 extends Functor1 { + readonly alt: (fa: KindOf, that: Lazy>) => KindOf +} + +export interface Alt2 extends Functor2 { + readonly alt: (fa: KindOf, that: Lazy>) => KindOf +} diff --git a/src/Functors/Alternative.ts b/src/Functors/Alternative.ts index e69de29..fbebea3 100644 --- a/src/Functors/Alternative.ts +++ b/src/Functors/Alternative.ts @@ -0,0 +1,16 @@ +/** + * Alternative + * + * 1. x.ap(f.alt(g)) is equivalent to x.ap(f).alt(x.ap(g)) (distributivity) + * 2. x.ap(A.zero()) is equivalent to A.zero() (annihilation) + */ + +import { URIS } from './HKT' +import { Plus, Plus1, Plus2 } from './Plus' +import { Applicative, Applicative1, Applicative2 } from './Applicative' + +export interface Alternative extends Plus, Applicative {} + +export interface Alternative1 extends Plus1, Applicative1 {} + +export interface Alternative2 extends Plus2, Applicative2 {} diff --git a/src/Functors/Applicative.ts b/src/Functors/Applicative.ts index e69de29..42ad54b 100644 --- a/src/Functors/Applicative.ts +++ b/src/Functors/Applicative.ts @@ -0,0 +1,24 @@ +/** + * Applicative + * + * 1. v.ap(A.of(x => x)) is equivalent to v (identity) + * 2. A.of(x).ap(A.of(f)) is equivalent to A.of(f(x)) (homomorphism) + * 3. A.of(y).ap(u) is equivalent to u.ap(A.of(f => f(y))) (interchange) + * + * of :: Applicative f => a -> f a + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Apply, Apply1, Apply2 } from './Apply' + +export interface Applicative extends Apply { + readonly of: (ma: A) => HKT +} + +export interface Applicative1 extends Apply1 { + readonly of: (ma: A) => KindOf +} + +export interface Applicative2 extends Apply2 { + readonly of: (ma: A) => KindOf +} diff --git a/src/Functors/Apply.ts b/src/Functors/Apply.ts index e69de29..d280f6a 100644 --- a/src/Functors/Apply.ts +++ b/src/Functors/Apply.ts @@ -0,0 +1,22 @@ +/** + * Apply + * + * 1. v.ap(u.ap(a.map(f => g => x => f(g(x))))) is equivalent to v.ap(u).ap(a) (composition) + * + * ap :: Apply f => f a ~> f (a -> b) -> f b + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Functor, Functor1, Functor2 } from './Functor' + +export interface Apply extends Functor { + readonly ap: (fab: HKT B>, fa: HKT) => HKT +} + +export interface Apply1 extends Functor1 { + readonly ap: (fab: KindOf B]>, fa: KindOf) => KindOf +} + +export interface Apply2 extends Functor2 { + readonly ap: (fab: KindOf B]>, fa: KindOf) => KindOf +} diff --git a/src/Functors/Bifunctor.ts b/src/Functors/Bifunctor.ts index e69de29..cda410e 100644 --- a/src/Functors/Bifunctor.ts +++ b/src/Functors/Bifunctor.ts @@ -0,0 +1,15 @@ +/** + * Bifunctor + * + * 1. p.bimap(a => a, b => b) is equivalent to p (identity) + * 2. p.bimap(a => f(g(a)), b => h(i(b)) is equivalent to p.bimap(g, i).bimap(f, h) (composition) + * + * bimap :: Bifunctor f => f a c ~> (a -> b, c -> d) -> f b d + */ + +import { HKT, URIS, KindOf } from './HKT' // TODO: HKT2... +import { Functor2 } from './Functor' + +export interface Bifunctor2 extends Functor2 { + readonly bimap: (fea: KindOf, f: (e: E) => G, g: (a: A) => B) => KindOf +} diff --git a/src/Functors/Category.ts b/src/Functors/Category.ts index e69de29..3dcc65e 100644 --- a/src/Functors/Category.ts +++ b/src/Functors/Category.ts @@ -0,0 +1,22 @@ +/** + * Category + * + * 1. a.compose(C.id()) is equivalent to a (right identity) + * 2. C.id().compose(a) is equivalent to a (left identity) + * + * compose :: Category c => c i j ~> c j k -> c i k + */ + +import { HKT, URIS, KindOf } from './HKT' + +export interface Category { + readonly id: () => HKT +} + +export interface Category1 { + readonly id: () => KindOf +} + +export interface Category2 { + readonly id: () => KindOf +} diff --git a/src/Functors/Chain.ts b/src/Functors/Chain.ts index e69de29..d625f8a 100644 --- a/src/Functors/Chain.ts +++ b/src/Functors/Chain.ts @@ -0,0 +1,22 @@ +/** + * Chain + * + * 1. m.chain(f).chain(g) is equivalent to m.chain(x => f(x).chain(g)) (associativity) + * + * chain :: Chain m => m a ~> (a -> m b) -> m b + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Apply, Apply1, Apply2 } from './Apply' + +export interface Chain extends Apply { + readonly chain: (fa: HKT, f: (a: A) => HKT) => HKT +} + +export interface Chain1 extends Apply1 { + readonly chain: (fa: KindOf, f: (a: A) => KindOf) => KindOf +} + +export interface Chain2 extends Apply2 { + readonly chain: (fa: KindOf, f: (a: A) => KindOf) => KindOf +} diff --git a/src/Functors/ChainRec.ts b/src/Functors/ChainRec.ts index e69de29..d2864f1 100644 --- a/src/Functors/ChainRec.ts +++ b/src/Functors/ChainRec.ts @@ -0,0 +1,24 @@ +/** + * ChainRec + * + * 1. M.chainRec((next, done, v) => p(v) ? d(v).map(done) : n(v).map(next), i) is equivalent to + * (function step(v) { return p(v) ? d(v) : n(v).chain(step); }(i)) (equivalence) + * 2. Stack usage of M.chainRec(f, i) must be at most a constant multiple of the stack usage of f itself + * + * chainRec :: ChainRec m => ((a -> c, b -> c, a) -> m c, a) -> m b + */ + +import { HKT, URIS, KindOf, Kind } from './HKT' +import { Chain, Chain1, Chain2 } from './Chain' + +export interface ChainRec extends Chain { + readonly chainRec: (f: (loop: (a: A) => C, done: (b: B) => C, init: A) => HKT, fi: A) => HKT +} + +export interface ChainRec1 extends Chain1 { + readonly chainRec: (f: (loop: (a: A) => C, done: (b: B) => C, init: A) => KindOf, fi: A) => KindOf +} + +export interface ChainRec2 extends Chain2 { + readonly chainRec: (f: (loop: (a: A) => C, done: (b: B) => C, init: A) => KindOf, fi: A) => KindOf +} diff --git a/src/Functors/Comonad.ts b/src/Functors/Comonad.ts index e69de29..5462438 100644 --- a/src/Functors/Comonad.ts +++ b/src/Functors/Comonad.ts @@ -0,0 +1,23 @@ +/** + * Comonad + * + * 1. w.extend(_w => _w.extract()) is equivalent to w (left identity) + * 2. w.extend(f).extract() is equivalent to f(w) (right identity) + * + * extract :: Comonad w => w a ~> () -> a + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Extend, Extend1, Extend2 } from './Extend' + +export interface Comonad extends Extend { + readonly extract: (wa: HKT) => A +} + +export interface Comonad1 extends Extend1 { + readonly extract: (wa: KindOf) => A +} + +export interface Comonad2 extends Extend2 { + readonly extract: (wa: KindOf) => A +} diff --git a/src/Functors/Contravariant.ts b/src/Functors/Contravariant.ts index e69de29..032229d 100644 --- a/src/Functors/Contravariant.ts +++ b/src/Functors/Contravariant.ts @@ -0,0 +1,22 @@ +/** + * Contravariant + * + * 1. u.contramap(a => a) is equivalent to u (identity) + * 2. u.contramap(x => f(g(x))) is equivalent to u.contramap(f).contramap(g) (composition) + * + * contramap :: Contravariant f => f a ~> (b -> a) -> f b + */ + +import { HKT, URIS, KindOf } from './HKT' + +export interface Contravariant { + readonly contramap: (fa: HKT, f: (b: B) => A) => HKT +} + +export interface Contravariant1 { + readonly contramap: (fa: KindOf, f: (b: B) => A) => KindOf +} + +export interface Contravariant2 { + readonly contramap: (fa: KindOf, f: (b: B) => A) => KindOf +} diff --git a/src/Functors/Extend.ts b/src/Functors/Extend.ts index e69de29..232517f 100644 --- a/src/Functors/Extend.ts +++ b/src/Functors/Extend.ts @@ -0,0 +1,22 @@ +/** + * Extend + * + * 1. w.extend(g).extend(f) is equivalent to w.extend(_w => f(_w.extend(g))) + * + * extend :: Extend w => w a ~> (w a -> b) -> w b + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Functor, Functor1, Functor2 } from './Functor' + +export interface Extend extends Functor { + readonly extend: (wa: HKT, f: (wa: HKT) => B) => HKT +} + +export interface Extend1 extends Functor1 { + readonly extend: (wa: KindOf, f: (wa: KindOf) => B) => KindOf +} + +export interface Extend2 extends Functor2 { + readonly extend: (wa: KindOf, f: (wa: KindOf) => B) => KindOf +} diff --git a/src/Functors/Filterable.ts b/src/Functors/Filterable.ts new file mode 100644 index 0000000..ab6be01 --- /dev/null +++ b/src/Functors/Filterable.ts @@ -0,0 +1,24 @@ +/** + * Filterable + * + * 1. v.filter(x => p(x) && q(x)) is equivalent to v.filter(p).filter(q) (distributivity) + * 2. v.filter(x => true) is equivalent to v (identity) + * 3. v.filter(x => false) is equivalent to w.filter(x => false) if v and w are values of the same Filterable (annihilation) + * + * filter :: Filterable f => f a ~> (a -> Boolean) -> f a + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Predicate } from '../Predicate' + +export interface Filterable { + readonly filter: (ma: HKT, predicate: Predicate) => HKT +} + +export interface Filterable1 { + readonly filter: (ma: KindOf, predicate: Predicate) => KindOf +} + +export interface Filterable2 { + readonly filter: (ma: KindOf, predicate: Predicate) => KindOf +} diff --git a/src/Functors/Foldable.ts b/src/Functors/Foldable.ts index e69de29..1ab2a13 100644 --- a/src/Functors/Foldable.ts +++ b/src/Functors/Foldable.ts @@ -0,0 +1,21 @@ +/** + * Foldable + * + * 1. u.reduce is equivalent to u.reduce((acc, x) => acc.concat([x]), []).reduce + * + * reduce :: Foldable f => f a ~> (b, (b, a) -> b) -> b + */ + +import { HKT, URIS, KindOf } from './HKT' + +export interface Foldable { + readonly reduce: (fa: HKT, b: B, f: (b: B, a: A) => B) => B +} + +export interface Foldable1 { + readonly reduce: (fa: KindOf, b: B, f: (b: B, a: A) => B) => KindOf +} + +export interface Foldable2 { + readonly reduce: (fa: KindOf, b: B, f: (b: B, a: A) => B) => KindOf +} diff --git a/src/Functors/Functor.ts b/src/Functors/Functor.ts index aeb396c..f352a21 100644 --- a/src/Functors/Functor.ts +++ b/src/Functors/Functor.ts @@ -1,34 +1,22 @@ +/** + * Functor + * + * 1. u.map(a => a) is equivalent to u (identity) + * 2. u.map(x => f(g(x))) is equivalent to u.map(g).map(f) (composition) + * + * map :: Functor f => f a ~> (a -> b) -> f b + */ + import { HKT, KindOf, URIS } from './HKT' export interface Functor { - readonly URI: F readonly map: (ma: HKT, f: (a: A) => B) => HKT } export interface Functor1 { - readonly URI: F readonly map: (ma: KindOf, f: (a: A) => B) => KindOf } export interface Functor2 { - readonly URI: F readonly map: (ma: KindOf, f: (a: A) => B) => KindOf } - -/** - * `map` composition. - */ -export function map( - F: Functor, - G: Functor2 -): (f: (a: A) => B) => (ma: HKT>) => HKT> -export function map( - F: Functor, - G: Functor1 -): (f: (a: A) => B) => (ma: HKT>) => HKT> -export function map( - F: Functor, - G: Functor -): (f: (a: A) => B) => (ma: HKT>) => HKT> { - return (f) => (ma) => F.map(ma, (a) => G.map(a, f)) -} diff --git a/src/Functors/Group.ts b/src/Functors/Group.ts index e69de29..86561b4 100644 --- a/src/Functors/Group.ts +++ b/src/Functors/Group.ts @@ -0,0 +1,23 @@ +/** + * Group + * + * 1. g.concat(g.invert()) is equivalent to g.constructor.empty() (right inverse) + * 2. g.invert().concat(g) is equivalent to g.constructor.empty() (left inverse) + * + * invert :: Group g => g ~> () -> g + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Monoid, Monoid1, Monoid2 } from './Monoid' + +export interface Group extends Monoid { + readonly invert: () => HKT +} + +export interface Group1 extends Monoid1 { + readonly invert: () => KindOf +} + +export interface Group2 extends Monoid2 { + readonly invert: () => KindOf +} diff --git a/src/Functors/Monad.ts b/src/Functors/Monad.ts index e69de29..56d6ce3 100644 --- a/src/Functors/Monad.ts +++ b/src/Functors/Monad.ts @@ -0,0 +1,16 @@ +/** + * Monad + * + * 1. M.of(a).chain(f) is equivalent to f(a) (left identity) + * 2. m.chain(M.of) is equivalent to m (right identity) + */ + +import { URIS } from './HKT' +import { Applicative, Applicative1, Applicative2 } from './Applicative' +import { Chain, Chain1, Chain2 } from './Chain' + +export interface Monad extends Applicative, Chain {} + +export interface Monad1 extends Applicative1, Chain1 {} + +export interface Monad2 extends Applicative2, Chain2 {} diff --git a/src/Functors/Monoid.ts b/src/Functors/Monoid.ts index e69de29..3c9429b 100644 --- a/src/Functors/Monoid.ts +++ b/src/Functors/Monoid.ts @@ -0,0 +1,23 @@ +/** + * Monoid + * + * 1. m.concat(M.empty()) is equivalent to m (right identity) + * 2. M.empty().concat(m) is equivalent to m (left identity) + * + * empty :: Monoid m => () -> m + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Semigroup, Semigroup1, Semigroup2 } from './Semigroup' + +export interface Monoid extends Semigroup { + readonly empty: () => HKT +} + +export interface Monoid1 extends Semigroup1 { + readonly empty: () => KindOf +} + +export interface Monoid2 extends Semigroup2 { + readonly empty: () => KindOf +} diff --git a/src/Functors/Ord.ts b/src/Functors/Ord.ts index e69de29..5a59b9c 100644 --- a/src/Functors/Ord.ts +++ b/src/Functors/Ord.ts @@ -0,0 +1,24 @@ +/** + * Ord + * + * 1. a.lte(b) or b.lte(a) (totality) + * 2. If a.lte(b) and b.lte(a), then a.equals(b) (antisymmetry) + * 3. If a.lte(b) and b.lte(c), then a.lte(c) (transitivity) + * + * lte :: Ord a => a ~> a -> Boolean + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Setoid, Setoid1, Setoid2 } from './Setoid' + +export interface Ord extends Setoid { + readonly lte: (a: HKT, b: HKT) => boolean +} + +export interface Ord1 extends Setoid1 { + readonly lte: (a: KindOf, b: KindOf) => boolean +} + +export interface Ord2 extends Setoid2 { + readonly lte: (a: KindOf, b: KindOf) => boolean +} diff --git a/src/Functors/Plus.ts b/src/Functors/Plus.ts index e69de29..83de8f8 100644 --- a/src/Functors/Plus.ts +++ b/src/Functors/Plus.ts @@ -0,0 +1,24 @@ +/** + * Plus + * + * 1. x.alt(A.zero()) is equivalent to x (right identity) + * 2. A.zero().alt(x) is equivalent to x (left identity) + * 3. A.zero().map(f) is equivalent to A.zero() (annihilation) + * + * zero :: Plus f => () -> f a + */ + +import { HKT, URIS, KindOf } from './HKT' +import { Alt, Alt2, Alt1 } from './Alt' + +export interface Plus extends Alt { + readonly zero: () => HKT +} + +export interface Plus1 extends Alt1 { + readonly zero: () => KindOf +} + +export interface Plus2 extends Alt2 { + readonly zero: () => KindOf +} diff --git a/src/Functors/Profunctor.ts b/src/Functors/Profunctor.ts index e69de29..dc85216 100644 --- a/src/Functors/Profunctor.ts +++ b/src/Functors/Profunctor.ts @@ -0,0 +1,16 @@ +/** + * Profunctor + * + * 1. p.promap(a => a, b => b) is equivalent to p (identity) + * 2. p.promap(a => f(g(a)), b => h(i(b))) is equivalent to p.promap(f, i).promap(g, h) (composition) + * + * promap :: Profunctor p => p b c ~> (a -> b, c -> d) -> p a d + */ + +import { HKT, URIS, KindOf } from './HKT' // TODO: HKT2 +import { Functor2 } from './Functor' + +export interface Profunctor2 extends Functor2 { + readonly promap: (fea: KindOf, f: (d: D) => E, g: (a: A) => B) => KindOf +} + diff --git a/src/Functors/Semigroup.ts b/src/Functors/Semigroup.ts index e69de29..58ec4ea 100644 --- a/src/Functors/Semigroup.ts +++ b/src/Functors/Semigroup.ts @@ -0,0 +1,22 @@ +/** + * Semigroup + * + * 1. a.concat(b).concat(c) is equivalent to a.concat(b.concat(c)) (associativity) + * + * concat :: Semigroup a => a ~> a -> a + */ + +import { HKT, URIS, KindOf } from './HKT' + +export interface Semigroup { + readonly concat: (a: HKT, b: HKT) => HKT +} + +export interface Semigroup1 { + readonly concat: (a: KindOf, b: KindOf) => KindOf +} + +export interface Semigroup2 { + readonly concat: (a: KindOf, b: KindOf) => KindOf +} + diff --git a/src/Functors/Semigroupoid.ts b/src/Functors/Semigroupoid.ts index e69de29..62e97f7 100644 --- a/src/Functors/Semigroupoid.ts +++ b/src/Functors/Semigroupoid.ts @@ -0,0 +1,21 @@ +/** + * Semigroupoid + * + * 1. a.compose(b).compose(c) === a.compose(b.compose(c)) (associativity) + * + * compose :: Semigroupoid c => c i j ~> c j k -> c i k + */ + +import { HKT, URIS, KindOf } from './HKT' + +export interface Semigroupoid { + readonly compose: (a: HKT, b: HKT) => HKT +} + +export interface Semigroupoid1 { + readonly compose: (a: KindOf, b: KindOf) => KindOf +} + +export interface Semigroupoid2 { + readonly compose: (a: KindOf, b: KindOf) => KindOf +} diff --git a/src/Functors/Setoid.ts b/src/Functors/Setoid.ts index e69de29..c34adce 100644 --- a/src/Functors/Setoid.ts +++ b/src/Functors/Setoid.ts @@ -0,0 +1,23 @@ +/** + * Setoid + * + * 1. a.equals(a) === true (reflexivity) + * 2. a.equals(b) === b.equals(a) (symmetry) + * 3. If a.equals(b) and b.equals(c), then a.equals(c) (transitivity) + * + * equals :: Setoid a => a ~> a -> Boolean + */ + +import { HKT, URIS, KindOf } from './HKT' + +export interface Setoid { + readonly equals: (a: HKT, b: HKT) => boolean + } + +export interface Setoid1 { + readonly equals: (a: KindOf, b: KindOf) => boolean + } + +export interface Setoid2 { + readonly equals: (a: KindOf, b: KindOf) => boolean +} diff --git a/src/Functors/Traversable.ts b/src/Functors/Traversable.ts index e69de29..51f7283 100644 --- a/src/Functors/Traversable.ts +++ b/src/Functors/Traversable.ts @@ -0,0 +1,28 @@ +/** + * Traversable + * + * 1. t(u.traverse(F, x => x)) is equivalent to u.traverse(G, t) for any t such that + * t(a).map(f) is equivalent to t(a.map(f)) (naturality) + * 2. u.traverse(F, F.of) is equivalent to F.of(u) for any Applicative F (identity) + * 3. u.traverse(Compose, x => new Compose(x)) is equivalent to new Compose(u.traverse(F, x => x).map(x => x.traverse(G, x => x))) + * for Compose defined below and any Applicatives F and G (composition) + * + * traverse :: Applicative f, Traversable t => t a ~> (TypeRep f, a -> f b) -> f (t b) + */ + +import { HKT, KindOf, URIS } from './HKT' +import { Functor, Functor1, Functor2 } from './Functor' +import { Foldable, Foldable1, Foldable2 } from './Foldable' +import { Applicative } from './Applicative' + +export interface Traversable extends Functor, Foldable { + readonly traverse: (A: Applicative) => (ma: HKT, f: (a: A) => HKT) => HKT +} + +export interface Traversable1 extends Functor1, Foldable1 { + readonly traverse: (A: Applicative) => (ma: KindOf, f: (a: A) => KindOf) => KindOf +} + +export interface Traversable2 extends Functor2, Foldable2 { + readonly traverse: (A: Applicative) => (ma: KindOf, f: (a: A) => KindOf) => KindOf +}