-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
everything #1
Open
davidchambers
wants to merge
42
commits into
main
Choose a base branch
from
davidchambers/everything
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+742
−0
Open
everything #1
Changes from all commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
c1474b4
everything
davidchambers 7d322ca
[email protected]
davidchambers 3145b1b
[email protected]
davidchambers 4c087c8
[email protected]
davidchambers 08e0b5b
[email protected]
davidchambers b4a89ad
[email protected]
davidchambers e16d2f5
[email protected]
davidchambers fbad400
[email protected]
davidchambers 63db317
[email protected]
davidchambers 89c922c
[email protected]
davidchambers 7b221f0
[email protected]
davidchambers 254bd77
add FUNDING.yml
davidchambers eb27a56
circle: housekeeping
davidchambers 828e36d
[email protected]
davidchambers 0985701
[email protected]
davidchambers 79b0e9d
[email protected]
davidchambers 0cf9726
[email protected]
davidchambers aa97ae8
[email protected]
davidchambers 58ba764
[email protected]
davidchambers ca5ad65
[email protected]
davidchambers 1391050
remove ‘inspect’ fallback
davidchambers 3fcecc8
use ES6 syntax
davidchambers ca95f9e
documentation: use S.show in doctest
davidchambers b351ccd
[email protected]
davidchambers 9601e97
support Deno.inspect
davidchambers 8af3f8b
circle: create test matrix without nvm
davidchambers af4ebcc
[email protected]
davidchambers b262895
eslint: use "readonly" for globals in place of deprecated value
davidchambers 9221f73
circle: update Node versions
davidchambers 4faa68c
update references to default branch
davidchambers ea3d022
[email protected]
davidchambers 2eec761
convert test modules to ES modules
davidchambers bcd5ca1
[email protected]
davidchambers 0ed036c
use `globalThis` and `?.` operator to simplify feature detection
davidchambers 45ce4bd
use `assert.deepStrictEqual`
davidchambers 0ee27cf
use `node:` imports
davidchambers 8b733b7
test `util.inspect` compatibility
davidchambers f6ba464
[email protected]
davidchambers 0f6c194
[email protected]
davidchambers e7cd612
use ES modules
davidchambers 5bdb4d2
use `\x1B[22m` to reset intensity but not colour
davidchambers 042bd46
circle: update Node versions
davidchambers File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
version: 2.1 | ||
|
||
orbs: | ||
node: circleci/[email protected] | ||
|
||
workflows: | ||
test: | ||
jobs: | ||
- node/test: | ||
setup: | ||
# derive cache key from package.json | ||
- run: cp package.json package-lock.json | ||
override-ci-command: rm package-lock.json && npm install && git checkout -- package.json | ||
matrix: | ||
parameters: | ||
version: | ||
- 18.0.0 | ||
- 20.0.0 | ||
- 22.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
repo-owner = sanctuary-js | ||
repo-name = sanctuary-constant | ||
contributing-file = .github/CONTRIBUTING.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"root": true, | ||
"extends": ["./node_modules/sanctuary-style/eslint.json"], | ||
"parserOptions": {"ecmaVersion": 2020, "sourceType": "module"}, | ||
"globals": {"globalThis": "readonly"} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Contributing | ||
|
||
Note: __README.md__ is generated from comments in __index.js__. Do not modify | ||
__README.md__ directly. | ||
|
||
1. Update local main branch: | ||
|
||
$ git checkout main | ||
$ git pull upstream main | ||
|
||
2. Create feature branch: | ||
|
||
$ git checkout -b feature-x | ||
|
||
3. Make one or more atomic commits, and ensure that each commit has a | ||
descriptive commit message. Commit messages should be line wrapped | ||
at 72 characters. | ||
|
||
4. Run `npm test`, and address any errors. Preferably, fix commits in place | ||
using `git rebase` or `git commit --amend` to make the changes easier to | ||
review. | ||
|
||
5. Push: | ||
|
||
$ git push origin feature-x | ||
|
||
6. Open a pull request. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
github: [davidchambers] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/coverage/ | ||
/node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package-lock=false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2019 Sanctuary | ||
|
||
Permission is hereby granted, free of charge, to any person | ||
obtaining a copy of this software and associated documentation | ||
files (the "Software"), to deal in the Software without | ||
restriction, including without limitation the rights to use, | ||
copy, modify, merge, publish, distribute, sublicense, and/or | ||
sell copies of the Software, and to permit persons to whom the | ||
Software is furnished to do so, subject to the following | ||
conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,283 @@ | ||
/* _____ _____ _____ _____ ______ _____ _____ ______ */ | ||
/* | | | | | | | | | | | | | | | | */ | ||
/* | |__| | | | | | | | |__| '-, ,-' | | | | | | '-, ,-' */ | ||
/* | |__ | | | | | | |__ | | | | | | | | | | */ | ||
/* | | | | | | | | | | | | | | | | | | | | | | */ | ||
/* |_____| |_____| |__|__| |_____| |__| |__|__| |__|__| |__| */ | ||
|
||
//. <a href="https://github.com/fantasyland/fantasy-land"><img alt="Fantasy Land" src="https://raw.githubusercontent.com/fantasyland/fantasy-land/master/logo.png" width="75" height="75" align="left"></a> | ||
//. | ||
//. # sanctuary-constant | ||
//. | ||
//. A value of type `Constant a b` always contains exactly one value, | ||
//. of type `a`. Mapping over a `Constant a b` has no effect because | ||
//. the `b -> c` function is never applied. | ||
|
||
import show from 'sanctuary-show'; | ||
import Z from 'sanctuary-type-classes'; | ||
|
||
export {Constant}; | ||
|
||
const constantTypeIdent = 'sanctuary-constant/Constant@1'; | ||
|
||
//. ```javascript | ||
//. > import S from 'sanctuary' | ||
//. > import $ from 'sanctuary-def' | ||
//. > import Useless from 'sanctuary-useless' | ||
//. ``` | ||
//. | ||
//. `Constant a b` satisfies the following [Fantasy Land][] specifications: | ||
//. | ||
//. ```javascript | ||
//. > S.map (k => | ||
//. . k + ' '.repeat (16 - k.length) + | ||
//. . (Z[k].test (Constant (Useless.constructor) (Useless)) ? '\u2705 ' : | ||
//. . Z[k].test (Constant (Array) (['foo', 'bar', 'baz'])) ? '\u2705 * ' : | ||
//. . /* otherwise */ '\u274C ') | ||
//. . ) (S.keys (S.unchecked.filter (S.is ($.TypeClass)) (Z))) | ||
//. [ 'Setoid ✅ * ', // if ‘a’ satisfies Setoid | ||
//. . 'Ord ✅ * ', // if ‘a’ satisfies Ord | ||
//. . 'Semigroupoid ❌ ', | ||
//. . 'Category ❌ ', | ||
//. . 'Semigroup ✅ * ', // if ‘a’ satisfies Semigroup | ||
//. . 'Monoid ❌ ', | ||
//. . 'Group ❌ ', | ||
//. . 'Filterable ❌ ', | ||
//. . 'Functor ✅ ', | ||
//. . 'Bifunctor ✅ ', | ||
//. . 'Profunctor ❌ ', | ||
//. . 'Apply ✅ * ', // if ‘a’ satisfies Semigroup | ||
//. . 'Applicative ✅ * ', // if ‘a’ satisfies Monoid | ||
//. . 'Chain ❌ ', | ||
//. . 'ChainRec ❌ ', | ||
//. . 'Monad ❌ ', | ||
//. . 'Alt ❌ ', | ||
//. . 'Plus ❌ ', | ||
//. . 'Alternative ❌ ', | ||
//. . 'Foldable ✅ ', | ||
//. . 'Traversable ✅ ', | ||
//. . 'Extend ❌ ', | ||
//. . 'Comonad ❌ ', | ||
//. . 'Contravariant ❌ ' ] | ||
//. ``` | ||
|
||
//# Constant :: TypeRep a -> a -> Constant a b | ||
//. | ||
//. Constant's sole data constructor. The [type representative][] makes | ||
//. `Constant (M)` an [Applicative][]-compatible type representative if | ||
//. `M` represents some monoidal type. | ||
//. | ||
//. ```javascript | ||
//. > Constant (String) ('abc') | ||
//. Constant (String) ('abc') | ||
//. | ||
//. > Constant (Number) (123) | ||
//. Constant (Number) (123) | ||
//. ``` | ||
const Constant = A => { | ||
const prototype = { | ||
/* eslint-disable key-spacing */ | ||
'constructor': Constant$bound, | ||
'@@type': constantTypeIdent, | ||
'@@show': Constant$prototype$show, | ||
'fantasy-land/map': Constant$prototype$map, | ||
'fantasy-land/bimap': Constant$prototype$bimap, | ||
'fantasy-land/reduce': Constant$prototype$reduce, | ||
'fantasy-land/traverse': Constant$prototype$traverse, | ||
/* eslint-enable key-spacing */ | ||
}; | ||
|
||
if (globalThis.process?.versions?.node != null) { | ||
const inspect = Symbol.for ('nodejs.util.inspect.custom'); | ||
prototype[inspect] = Constant$prototype$show; | ||
} | ||
|
||
/* c8 ignore start */ | ||
if (typeof globalThis.Deno?.customInspect === 'symbol') { | ||
const inspect = globalThis.Deno.customInspect; | ||
prototype[inspect] = Constant$prototype$show; | ||
} | ||
/* c8 ignore stop */ | ||
|
||
function Constant$bound(value) { | ||
const constant = Object.create (prototype); | ||
if (Z.Setoid.test (value)) { | ||
constant['fantasy-land/equals'] = Constant$prototype$equals; | ||
if (Z.Ord.test (value)) { | ||
constant['fantasy-land/lte'] = Constant$prototype$lte; | ||
} | ||
} | ||
if (Z.Semigroup.test (value)) { | ||
constant['fantasy-land/concat'] = Constant$prototype$concat; | ||
constant['fantasy-land/ap'] = Constant$prototype$ap; | ||
} | ||
constant.value = value; | ||
return constant; | ||
} | ||
|
||
// XXX: sanctuary-show@3 only respects @@show on "objects". Fool it. | ||
Constant$bound[Symbol.toStringTag] = 'Object'; | ||
|
||
Constant$bound['@@show'] = () => { | ||
if (!(Object.prototype.hasOwnProperty.call (A, 'name'))) { | ||
const source = String (A); | ||
const match = /^\s*function ([$_A-Za-z][$_A-Za-z0-9]*)/.exec (source); | ||
return 'Constant (' + (match == null ? source : match[1]) + ')'; | ||
} else if (A.name === Constant$bound.name) { | ||
return 'Constant (' + show (A) + ')'; | ||
} else { | ||
return 'Constant (' + A.name + ')'; | ||
} | ||
}; | ||
|
||
//# Constant.fantasy-land/of :: Monoid m => a -> Constant m a | ||
//. | ||
//. `of (Constant (M)) (x)` is equivalent to `Constant (M) (empty (M))`. | ||
//. | ||
//. ```javascript | ||
//. > S.of (Constant (Array)) (42) | ||
//. Constant (Array) ([]) | ||
//. | ||
//. > S.of (Constant (String)) (42) | ||
//. Constant (String) ('') | ||
//. ``` | ||
(() => { | ||
let empty; | ||
try { empty = Z.empty (A); } catch (err) { return; } | ||
Constant$bound['fantasy-land/of'] = x => Constant$bound (empty); | ||
}) (); | ||
|
||
//# Constant#@@show :: Showable a => Constant a b ~> () -> String | ||
//. | ||
//. `show (Constant (A) (x))` is equivalent to | ||
//. `'Constant (' + A.name + ') (' + show (x) + ')'`. | ||
//. | ||
//. ```javascript | ||
//. > S.show (Constant (Array) (['foo', 'bar', 'baz'])) | ||
//. 'Constant (Array) (["foo", "bar", "baz"])' | ||
//. ``` | ||
function Constant$prototype$show() { | ||
return show (Constant$bound) + ' (' + show (this.value) + ')'; | ||
} | ||
|
||
//# Constant#fantasy-land/equals :: Setoid a => Constant a b ~> Constant a b -> Boolean | ||
//. | ||
//. `Constant (A) (x)` is equal to `Constant (A) (y)` [iff][] `x` is | ||
//. equal to `y` according to [`Z.equals`][]. | ||
//. | ||
//. ```javascript | ||
//. > S.equals (Constant (Array) ([1, 2, 3])) | ||
//. . (Constant (Array) ([1, 2, 3])) | ||
//. true | ||
//. | ||
//. > S.equals (Constant (Array) ([1, 2, 3])) | ||
//. . (Constant (Array) ([3, 2, 1])) | ||
//. false | ||
//. ``` | ||
function Constant$prototype$equals(other) { | ||
return Z.equals (this.value, other.value); | ||
} | ||
|
||
//# Constant#fantasy-land/lte :: Ord a => Constant a b ~> Constant a b -> Boolean | ||
//. | ||
//. `Constant (A) (x)` is less than or equal to `Constant (A) (y)` [iff][] | ||
//. `x` is less than or equal to `y` according to [`Z.lte`][]. | ||
//. | ||
//. ```javascript | ||
//. > S.filter (S.lte (Constant (Number) (1))) | ||
//. . ([Constant (Number) (0), | ||
//. . Constant (Number) (1), | ||
//. . Constant (Number) (2)]) | ||
//. [Constant (Number) (0), Constant (Number) (1)] | ||
//. ``` | ||
function Constant$prototype$lte(other) { | ||
return Z.lte (this.value, other.value); | ||
} | ||
|
||
//# Constant#fantasy-land/concat :: Semigroup a => Constant a b ~> Constant a b -> Constant a b | ||
//. | ||
//. `concat (Constant (A) (x)) (Constant (A) (y))` is equivalent to | ||
//. `Constant (A) (concat (x) (y))`. | ||
//. | ||
//. ```javascript | ||
//. > S.concat (Constant (Array) ([1, 2, 3])) | ||
//. . (Constant (Array) ([4, 5, 6])) | ||
//. Constant (Array) ([1, 2, 3, 4, 5, 6]) | ||
//. ``` | ||
function Constant$prototype$concat(other) { | ||
return Constant$bound (Z.concat (this.value, other.value)); | ||
} | ||
|
||
//# Constant#fantasy-land/map :: Constant a b ~> (b -> c) -> Constant a c | ||
//. | ||
//. `map (f) (Constant (A) (x))` is equivalent to `Constant (A) (x)`. | ||
//. | ||
//. ```javascript | ||
//. > S.map (Math.sqrt) (Constant (Number) (64)) | ||
//. Constant (Number) (64) | ||
//. ``` | ||
function Constant$prototype$map(f) { | ||
return this; | ||
} | ||
|
||
//# Constant#fantasy-land/bimap :: Constant a c ~> (a -> b, c -> d) -> Constant b d | ||
//. | ||
//. `bimap (f) (g) (Constant (A) (x))` is equivalent to | ||
//. `Constant (A) (f (x))`. | ||
//. | ||
//. ```javascript | ||
//. > S.bimap (s => s.length) (Math.sqrt) (Constant (String) ('abc')) | ||
//. Constant (Number) (3) | ||
//. ``` | ||
function Constant$prototype$bimap(f, g) { | ||
const x = f (this.value); | ||
return Constant (x.constructor) (x); | ||
} | ||
|
||
//# Constant#fantasy-land/ap :: Semigroup a => Constant a b ~> Constant a (b -> c) -> Constant a c | ||
//. | ||
//. `ap (Constant (A) (x)) (Constant (A) (y))` is equivalent to | ||
//. `concat (Constant (A) (x)) (Constant (A) (y))`. | ||
//. | ||
//. ```javascript | ||
//. > S.ap (Constant (Array) ([1, 2, 3])) (Constant (Array) ([4, 5, 6])) | ||
//. Constant (Array) ([1, 2, 3, 4, 5, 6]) | ||
//. ``` | ||
function Constant$prototype$ap(other) { | ||
return Z.concat (other, this); | ||
} | ||
|
||
//# Constant#fantasy-land/reduce :: Constant a b ~> ((c, b) -> c, c) -> c | ||
//. | ||
//. `reduce (f) (x) (Constant (A) (y))` is equivalent to `x`. | ||
//. | ||
//. ```javascript | ||
//. > S.reduce (S.add) (100) (Constant (Number) (42)) | ||
//. 100 | ||
//. ``` | ||
function Constant$prototype$reduce(f, x) { | ||
return x; | ||
} | ||
|
||
//# Constant#fantasy-land/traverse :: Applicative f => Constant a b ~> (TypeRep f, b -> f c) -> f (Constant a c) | ||
//. | ||
//. `traverse (A) (f) (Constant (X) (x))` is equivalent to | ||
//. `of (A) (Constant (X) (x))`. | ||
//. | ||
//. ```javascript | ||
//. > S.traverse (Array) (Math.sqrt) (Constant (Number) (64)) | ||
//. [Constant (Number) (64)] | ||
//. ``` | ||
function Constant$prototype$traverse(typeRep, f) { | ||
return Z.of (typeRep, this); | ||
} | ||
|
||
return Constant$bound; | ||
}; | ||
|
||
//. [Applicative]: v:fantasyland/fantasy-land#Applicative | ||
//. [Fantasy Land]: v:fantasyland/fantasy-land | ||
//. [`Z.equals`]: v:sanctuary-js/sanctuary-type-classes#equals | ||
//. [`Z.lte`]: v:sanctuary-js/sanctuary-type-classes#lte | ||
//. [iff]: https://en.wikipedia.org/wiki/If_and_only_if | ||
//. [type representative]: v:fantasyland/fantasy-land#type-representatives |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really understand the Constant type, why it takes a type representative, and how that type representative relates to Constant's the type parameters. If you care to explain it to me, maybe that explanation can be added here to the introduction. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Haskell, we can do this:
We provided
42 :: Int
in “b
” position;"" :: String
materialized in “a
” position.In JavaScript, keeping track of
a
andb
in the type system is not an option so we must provide type information explicitly:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah. o.o .... Ahh, because String is a Monoid. So
Constant (Boolean)
will throw when instantiated.Alright. That makes things clearer. I don't really see how this would be used in practice, and that's probably what most of my confusion stems from.