-
Notifications
You must be signed in to change notification settings - Fork 26
added support for instanceof with both the returned union Type and the sub type constructors #36
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
base: master
Are you sure you want to change the base?
Conversation
…e sub type constructors
2. Don't create record constructors if fields isn't a dictionary
@paldepind, I urge you to reconsider supporting |
@davidchambers to be clear, neither the existing
both
and
would return |
@davidchambers Your description of |
$ cat index.js
const Foo = require('foo');
const isFoo = require('is-foo');
console.log(isFoo(new Foo()));
$ cat node_modules/foo/index.js
module.exports = function Foo() {};
$ cat node_modules/is-foo/index.js
const Foo = require('foo');
module.exports = x => x instanceof Foo;
$ cat node_modules/is-foo/node_modules/foo/index.js
module.exports = function Foo() {};
$ node index.js
false Even though the two |
@davidchambers it sounds like what you object to fundamentally, is javascript object equality?
I don't find this surprising; it's consistent with javascript semantics (as I understand them). eg:
|
}); | ||
it('constructor can be used with instanceof', function() { | ||
var Point = Type({Point: [isNumber, isNumber]}); | ||
assert.equal(Point.Point(4,2) instanceof Point.Point, true); |
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.
Why should Point.Point
be an instance of the constructor for a Point
? This doesn't seem right to me. Point
represents a type. But Point.Point
is just a function that creates a value of the type.
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 agree!
Instead, we should create one predicate per data constructor. For example:
// Maybe :: Type
const Maybe = Type({Nothing: [], Just: [R.T]});
// Maybe.isNothing :: Maybe a -> Boolean
// Maybe.isJust :: Maybe a -> Boolean
Maybe.isNothing(Maybe.Nothing()); // => true
Maybe.isNothing(Maybe.Just(42)); // => false
Maybe.isJust(Maybe.Nothing()); // => false
Maybe.isJust(Maybe.Just(42)); // => true
I agree with @davidchambers that |
Consistent, yes; helpful, no.
Every module which exports functions which take or return values of the Maybe type must also export the type itself (even if it's defined by a third-party library). const Maybe = require('maybe-type');
const quux = require('quux');
// blah :: Maybe Number
const blah = quux.parseBlah('…');
// Doesn't work, because `toArray` uses `instanceof` check.
Maybe.toArray(blah);
// We must use `quux.Maybe.toArray` instead.
quux.Maybe.toArray(blah); Furthermore, we may want to operate on multiple values of type // foreignMaybeToMaybe :: ForeignMaybe a -> Maybe a
const foreignMaybeToMaybe = maybe =>
maybe.isJust ? Maybe.Just(maybe.value) : Maybe.Nothing(); Let's avoid this complexity if possible. Let's provide a |
The |
addresses problem mentioned in #32