-
Notifications
You must be signed in to change notification settings - Fork 376
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
require static methods to be defined on type representatives #180
Merged
davidchambers
merged 1 commit into
fantasyland:master
from
davidchambers:type-representatives
Oct 23, 2016
Merged
Changes from all commits
Commits
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
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
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 |
---|---|---|
|
@@ -23,8 +23,6 @@ const Id = require('./id'); | |
const Sum = tagged('v'); | ||
Sum[of] = Sum; | ||
Sum[empty] = () => Sum(''); | ||
Sum.prototype[of] = Sum[of]; | ||
Sum.prototype[empty] = Sum[empty]; | ||
Sum.prototype[map] = function(f) { | ||
return Sum(f(this.v)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't get this change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At some point I thought |
||
}; | ||
|
@@ -90,8 +88,8 @@ exports.monad = { | |
}; | ||
|
||
exports.monoid = { | ||
leftIdentity: test(x => monoid.leftIdentity(Id[of](Sum[empty]()))(equality)(Sum[of](x))), | ||
rightIdentity: test(x => monoid.rightIdentity(Id[of](Sum[empty]()))(equality)(Sum[of](x))), | ||
leftIdentity: test(x => monoid.leftIdentity(Sum)(equality)(x)), | ||
rightIdentity: test(x => monoid.rightIdentity(Sum)(equality)(x)), | ||
}; | ||
|
||
// Semigroup tests are broken otherwise for this. | ||
|
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
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
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
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 did not quite get last sentence, especially
Id :: TypeRep Identity
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 types are "real" in the sense that one actually references types in one's programs:
In JavaScript types are not referenced (except in comments):
In JavaScript the idea of types exists—as evidenced by the use of type signatures in comments—but there's no "type level"; only a "value level". Since we can't reference types at the type level, we must reference them at the value level. So, for each type we'd like a value which represents it. We call such values type representatives.
Let's consider some examples:
Number
is the representative of the Number type.Number
is the sole inhabitant of theTypeRep Number
type.Id
is the representative of the Identity type.Id
is the sole representative of theTypeRep Identity
type.The formatting above is very much intentional. The Number type exists only as an idea, so should not be formatted as code.
Number
, on the other hand, is a JavaScript value which represents the Number type (in addition to its role as a function fromAny
toNumber
).It took me a while to come to terms with the idea of type representatives. This sort of thinking is not natural in a dynamically typed language. I suggest reading sanctuary-js/sanctuary#64 if you have not already done so.
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.
The part which confused me was
Id :: TypeRep Identity
(Id
andIdentity
are different whenNumber
andNumber
are same) is it because we assume definition of Identity would be something like thistype Identity a = Id a
?So if we have:
Then is this true:?
will take a look at that issue more carefully
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 at least those last equations are wrong.
TypeRep Maybe
andTypeRep X
must be able to be combined intoTypeRep (Maybe X)
. Perhaps the type reps of constructors are functions, or probably better (since it'll be easier to analyze) you could have something that gives you($$) :: TypeRep f -> TypeRep a -> TypeRep (f a)
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.
If that $$ is data then you can easily analyze it!
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.
When we talk about "the Identity type" we're referring to a concept with no manifestation in JavaScript. When we talk about "
Id
" we're referring to a real thing: an identifier we could evaluate in a REPL.Id
lives in the world of values to the left of the colons;Identity
lives in the world of types to the right of the colons.Since the world of values and the world of types are separate, we needn't worry about naming collisions. This is valid:
Identity
on the left of the::
is a value, whereasIdentity
on the right is a type (a type constructor, actually).Similarly, we could name our type representative
Identity
rather thanId
without conflict:I hope this clarifies things a little. :)