Skip to content
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

Initial PR #3

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
db7dea6
Initial commit
JAForbes Oct 29, 2016
1be19e0
Removed comments from old eslint file
JAForbes Oct 29, 2016
332527e
add 'use strict'; pragmas
davidchambers Oct 29, 2016
7a93834
use conventional def formatting
davidchambers Oct 29, 2016
6251345
package.json: use 1.2.x format for dependency versions
davidchambers Oct 29, 2016
aa367cc
[email protected]
davidchambers Oct 29, 2016
e603535
license: remove blank line at end of file
davidchambers Oct 29, 2016
a0c9066
makefile: remove unused variable declarations
davidchambers Oct 29, 2016
a454568
use Unix line endings
davidchambers Oct 29, 2016
2bd7b57
makefile: use "--" separator
davidchambers Oct 29, 2016
725845c
makefile: increase branch coverage requirement to 100%
davidchambers Oct 29, 2016
600baca
package.json: remove "directories"
davidchambers Oct 29, 2016
47beacb
lint: remove ESLint exemptions
davidchambers Oct 29, 2016
502eebd
style: use ternary expressions
davidchambers Oct 29, 2016
ae51106
avoid "inconsistent" use of Array#concat
davidchambers Oct 29, 2016
adf4e6f
use explicit "!= null" guard
davidchambers Oct 29, 2016
3fbdf34
do not rely on constructor identity
davidchambers Oct 29, 2016
dd7977f
group and alphabetize imports
davidchambers Oct 29, 2016
1b52787
style: use more compact formatting
davidchambers Oct 29, 2016
ea3d441
style: use conventional identifier for sanctuary-def module
davidchambers Oct 29, 2016
afeb3aa
test: replace tape with mocha
davidchambers Oct 29, 2016
2910165
test: use assert.throws
davidchambers Oct 29, 2016
815349a
update .gitignore
davidchambers Oct 29, 2016
34ef3fd
test: rename file
davidchambers Oct 29, 2016
3b1f3e5
:%s/\<check\>/checkTypes/g
davidchambers Oct 29, 2016
809d2da
require "env" field
davidchambers Oct 29, 2016
00387fa
remove boundStaticCase
davidchambers Oct 29, 2016
dcb81e7
internal simplifications
davidchambers Oct 29, 2016
51f13c9
more internal simplifications
davidchambers Oct 29, 2016
551395c
remove one use of curryN
davidchambers Oct 29, 2016
dcc2df2
avoid type coercion
davidchambers Oct 29, 2016
7e8ce85
use Z.map
davidchambers Oct 29, 2016
69a1840
license: add @paldepind as a copyright holder
davidchambers Oct 29, 2016
5ce9ada
:%s/\<fn\>/f/g
davidchambers Oct 29, 2016
bbee16b
remove CaseRecordType
davidchambers Oct 29, 2016
4e28128
update package.json
davidchambers Oct 29, 2016
9031b74
add CONTRIBUTING.md
davidchambers Oct 29, 2016
3f700ab
makefile: integrate transcribe and xyz
davidchambers Oct 29, 2016
accdf45
remove BuiltInType
davidchambers Oct 29, 2016
b3ef66b
remove special case for typeof x === 'function'
davidchambers Oct 29, 2016
7a8e54c
change type of List.Nil from "() -> List a" to "List a"
davidchambers Oct 29, 2016
e6bd349
style: remove unnecessary { ... } block
davidchambers Oct 29, 2016
0fb99ff
test: tweak Maybe examples
davidchambers Oct 29, 2016
4d6dbd1
strip namespaces
davidchambers Oct 29, 2016
8ebd50d
progress towards unification with $.RecordType
davidchambers Oct 29, 2016
5f42911
remove duplication
davidchambers Oct 29, 2016
7d6df8a
test: use type variables
davidchambers Oct 29, 2016
4dee2e3
test: add namespace
davidchambers Oct 29, 2016
90f4a47
revert change to handling of nullary data constructors
davidchambers Oct 30, 2016
e7efb93
reinstate support for defining methods by mutating prototype
davidchambers Oct 30, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/coverage/
/node_modules/
27 changes: 27 additions & 0 deletions CONTRIBUTING.md
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 master branch:

$ git checkout master
$ git pull upstream master

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 `make lint 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.
25 changes: 25 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
The MIT License (MIT)

Copyright (c) 2016 Sanctuary
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we include the following as well?

Copyright (c) 2015 Simon Friis Vindum

If you just drew inspiration from union-type this isn't necessary, but if you used its source code as a starting point I believe Simon has copyright. Fortunately union-type is MIT-licensed. :)

/cc @paldepind

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add Copyright for Simon (unless he objects), I didn't reference the source until the final stages but the API design is his.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copyright (c) 2015 Simon Friis Vindum

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.
44 changes: 44 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
ESLINT = node_modules/.bin/eslint --config node_modules/sanctuary-style/eslint-es6.json --env es6
ISTANBUL = node_modules/.bin/istanbul
NPM = npm
TRANSCRIBE = node_modules/.bin/transcribe
XYZ = node_modules/.bin/xyz --repo [email protected]:sanctuary-js/sanctuary-union-type.git --script scripts/prepublish


.PHONY: all
all: LICENSE README.md

.PHONY: LICENSE
LICENSE:
cp -- '$@' '[email protected]'
sed 's/Copyright (c) .* Sanctuary/Copyright (c) $(shell git log --date=format:%Y --pretty=format:%ad | sort -r | head -n 1) Sanctuary/' '[email protected]' >'$@'
rm -- '[email protected]'

README.md: index.js
$(TRANSCRIBE) \
--heading-level 4 \
--url 'https://github.com/sanctuary-js/sanctuary-union-type/blob/v$(VERSION)/index.js#L{line}' \
-- '$<' \
| LC_ALL=C sed 's/<h4 name="\(.*\)#\(.*\)">\(.*\)\1#\2/<h4 name="\1.prototype.\2">\3\1#\2/' >'$@'


.PHONY: lint
lint:
$(ESLINT) --env node -- index.js
$(ESLINT) --env node --env mocha -- test/index.js


.PHONY: release-major release-minor release-patch
release-major release-minor release-patch:
@$(XYZ) --increment $(@:release-%=%)


.PHONY: setup
setup:
$(NPM) install


.PHONY: test
test:
$(ISTANBUL) cover node_modules/.bin/_mocha -- --ui tdd -- test/index.js
$(ISTANBUL) check-coverage --branches 100
12 changes: 12 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
dependencies:
override:
- printf '%s\n' color=false progress=false >.npmrc
- make setup

machine:
node:
version: 6.1.0

test:
override:
- make lint test
152 changes: 152 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
'use strict';

const $ = require('sanctuary-def');
const Z = require('sanctuary-type-classes');


// stripNamespace :: String -> String
const stripNamespace = s => s.slice(s.indexOf('/') + 1);
Copy link
Member

@safareli safareli Nov 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should happen if input is my-package/sub-package/Point ? maybe we should use lastIndexOf?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I've been assuming type identifiers contain one slash (/) at most.


// values :: Any -> Array a
const values = o =>
Array.isArray(o) ? o : Z.map(k => o[k], Object.keys(o));

// zipObj :: (Array String, Array a) -> StrMap a
const zipObj = (ks, vs) =>
ks.reduce((acc, k, idx) => { acc[k] = vs[idx]; return acc; }, {});

const a = $.TypeVariable('a');

const createIterator = function() {
return {
idx: 0,
val: this,
next() {
const keys = this.val._keys;
return this.idx === keys.length ?
{done: true} :
// eslint-disable-next-line no-plusplus
{value: this.val[keys[this.idx++]]};
},
};
};

const staticCase = (options, b, ...args) =>
b._name in options ?
options[b._name](...Z.concat(Z.map(k => b[k], b._keys), args)) :
options._(b);

const ObjConstructorOf = (prototype, keys, name, r) =>
Object.assign(Object.create(prototype), r, {
_keys: keys,
_name: name,
[Symbol.iterator]: createIterator,
});

const CreateCaseConstructor = (def, prototype, typeName, cases, k) => {
const unprefixedTypeName = stripNamespace(typeName);
const type = cases[k];
const isArray = Array.isArray(type);
const keys = Object.keys(type);
const types = isArray ? type : values(type);
const recordType = $.RecordType(isArray ? zipObj(keys, types) : type);

return {
[`${k}Of`]:
def(`${unprefixedTypeName}.${k}Of`,
{},
[recordType, recordType],
t => ObjConstructorOf(prototype, keys, k, t)),
[k]: isArray && type.length === 0 ?
ObjConstructorOf(prototype, keys, k, {}) :
def(`${unprefixedTypeName}.${k}`,
{},
Z.concat(types, [recordType]),
(...args) =>
ObjConstructorOf(prototype, keys, k, zipObj(keys, args))),
};
};


module.exports = opts => {

const def = $.create(opts);

const CreateUnionType = (typeName, _cases, prototype) => {
const unprefixedTypeName = stripNamespace(typeName);
// Type :: Type
const Type = $.NullaryType(
typeName,
x => x != null && x['@@type'] === typeName
);
const keys = Object.keys(_cases);
const env = Z.concat(opts.env, [Type]);
const def = $.create({checkTypes: opts.checkTypes, env});
const cases =
Z.map(xs => Z.map(x => x === undefined ? Type : x, xs),
_cases);
const constructors =
Z.map(k => CreateCaseConstructor(def, prototype, typeName, cases, k),
keys);
const caseRecordType =
$.RecordType(Z.map(x => $.Function(Z.concat(values(x), [a])), cases));

const instanceCaseDef =
def(`${unprefixedTypeName}::case`,
{},
[caseRecordType, a],
function(t) { return staticCase(t, this); });

Type.prototype = Object.assign(prototype, {
'@@type': typeName,
case: function(o, ...args) {
return '_' in o ?
staticCase.apply(null, [o, this]) :
instanceCaseDef.apply(this, Z.concat([o], args));
},
env,
});

Type.prototype.case.toString =
Type.prototype.case.inspect = instanceCaseDef.toString;

const staticCaseDef =
def(`${unprefixedTypeName}.case`,
{},
[caseRecordType, Type, a],
staticCase);

Type.case = function(o, ..._args) {
const args = Z.concat([o], _args);
return '_' in o ?
def('anonymous', {}, [$.Any, $.Any, $.Any], staticCase)(...args) :
staticCaseDef.apply(this, args);
};

Type.case.toString =
Type.case.inspect = staticCaseDef.toString;

return Object.assign(Type, ...constructors);
};

const Named =
def('UnionType.Named',
{},
[$.String, $.StrMap($.Any), $.Any],
(typeName, _cases) => CreateUnionType(typeName, _cases, {}));

const Anonymous =
def('UnionType.Anonymous',
{},
[$.StrMap($.Any), $.Any],
enums =>
CreateUnionType(`(${Object.keys(enums).join(' | ')})`, enums, {}));

const Class =
def('UnionType.Class',
{},
[$.String, $.StrMap($.Any), $.Object, $.Any],
CreateUnionType);

return {Anonymous, Named, Class};
};
32 changes: 32 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "sanctuary-union-type",
"version": "0.0.0",
"description": "Descendant of paldepind/union-type with more descriptive error messages",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/sanctuary-js/sanctuary-union-type.git"
},
"scripts": {
"test": "make lint test"
},
"dependencies": {
"sanctuary-def": "github:sanctuary-js/sanctuary-def",
"sanctuary-type-classes": "0.3.x"
},
"devDependencies": {
"eslint": "2.9.x",
"istanbul": "0.4.x",
"mocha": "3.x.x",
"ramda": "0.22.x",
"sanctuary-style": "0.3.x",
"transcribe": "0.5.x",
"xyz": "1.1.x"
},
"files": [
"/LICENSE",
"/README.md",
"/index.js",
"/package.json"
]
}
6 changes: 6 additions & 0 deletions scripts/prepublish
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -e

rm -f README.md
make
git add LICENSE README.md
Loading