-
-
Notifications
You must be signed in to change notification settings - Fork 20
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 #2
everything #2
Conversation
So sanctuary (or whomever) can use these implementations to help with FL compliance for built in types? For example |
of: 'of', | ||
reduce: 'reduce', | ||
sequence: 'sequence' | ||
}; |
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 not depend on fantasy-land
to get these constants? A change to them would probably be released as a major version, and you can always do like I did; provide both the "easy" names, and the fantasy-land prefixed names.
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.
Three things need to happen before this is an option. I just opened fantasyland/fantasy-land#139 for discussion. :)
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.
That's a shame -- any reason why sanctuary-js projects won't delegate to bundlers like browserify?
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.
any reason why sanctuary-js projects won't delegate to bundlers like browserify?
To what end, @rjmk? I'm certainly open to doing so, but it's not clear to me exactly what we stand to gain. I haven't done much front-end development in the past two and a half years, so I'm a bit out of touch. 😜
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.
Well, it gives control of how to bundle the code to the consumer. It also allows us to be much more flexible in which modules we use (as here). It makes the code cleaner.
It is trivial to generate standalone bundles from npm modules, and so you don't even need to be using a bundler to use an npm package on the front-end.
If we wanted to have a bower version available, we could bundle sanctuary-js projects into a dist/
folder.
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.
This all sounds reasonable to me. What about AMD? I just want to be clear how all the pieces fit together (and some of the pieces in question are foreign to me).
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've never used AMD, but the bundles produced by wzrd, for example, are AMD compatible
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.
Okay. I've converted the file to CommonJS format and added fantasy-land
as a dependency.
That's right! :)
It's better than that, even. The Functor instances for |
3f03088
to
0d3793a
Compare
//. | [Chain][] | ✔︎ | | | | | ||
//. | [Monad][] | | | | | | ||
//. | [Extend][] | | | | | | ||
//. | [Comonad][] | | | | | |
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.
Type class | Array | Function | Object | String |
---|---|---|---|---|
Setoid | ||||
Semigroup | ✔︎ | ✔︎ | ✔︎ | |
Monoid | ✔︎ | ✔︎ | ✔︎ | |
Functor | ✔︎ | ✔︎ | ✔︎ | |
Foldable | ✔︎ | |||
Traversable | ✔︎ | |||
Apply | ✔︎ | ✔︎ | ||
Applicative | ||||
Chain | ✔︎ | |||
Monad | ||||
Extend | ||||
Comonad |
Could we check any more of these cells? I think I've implemented all the ones Ramda does, plus Object#concat
(which is known as merge
in Ramda).
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.
Can we tick the applicative box for arrays?
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'm only after getting a chance to look into this now. I didn't appreciate fully what was going on but now I've read the code I really like it. Generalising the dispatching seems like it will be really powerful. This is great. |
|
||
//# Object$concat :: StrMap a ~> StrMap a | ||
methods.Object$concat = function(strMap) { | ||
var result = {}; |
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.
This implementation is a bit hard to follow, does it really need to depend on Array$map
? What's actually happening here?
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.
We're merging two values of type StrMap a
. Perhaps this implementation is clearer:
var result = [];
for (var k in this) if (hasOwnProperty_.call(this, k)) result[k] = this[k];
for (k in strMap) if (hasOwnProperty_.call(strMap, k)) result[k] = strMap[k];
return result;
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.
Yeah, I much prefer that implementation.
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.
⚡
0d3793a
to
446f320
Compare
Any reason why there's no |
I had it initially, but then realized that > λ.of([], 42)
[42]
> λ.of(S.Nothing(), 42)
Just(42)
> λ.of(S.Right(0), 42)
Right(42) Certain functions, such as † We could define |
But do we not need |
446f320
to
4b0d39d
Compare
Great point, Stefano! The |
7532cf4
to
73d1e73
Compare
73d1e73
to
319905d
Compare
0b4c2b0
to
c800b4c
Compare
c800b4c
to
4676623
Compare
4676623
to
2283bcf
Compare
f071574
to
6160174
Compare
I've spent the day sanding the patch. I'll merge this pull request tomorrow. You're welcome to take one last look before I do so. I'm particularly interested in knowing what people think of the readme. Having thought about and worked on this patch for several months I could easily have neglected to explain something important because I take it for granted. Let me know if this is the case. |
Looks good! A couple comments from someone who doesn't know much about this stuff :)
I'm not sure exactly what this means.. A TypeClass "value"? I think I understand it after I got a little farther down, but maybe there is a more generic way to phrase this at the top so novices such as myself aren't thrown off? Maybe replace "value" with "definition" or just leave the word out altogether?
Is this mostly a distinction between "function" and "method"? Is there actually a "Fantasy Land" instance that has methods?
|
This is the most important perspective. :)
Let me explain the distinction I'm attempting to make, and perhaps you can suggest a better way to phrase it. I'm using type class to refer to a group of types. JavaScript doesn't have types, so it doesn't have type classes, but the idea of type classes is still useful. I'm using
Again, it's possible I chose my words poorly. What I'm trying to say is that FL specifies the behaviour of I'm not sure what you mean by a "Fantasy Land" instance that has methods. Could you elaborate?
I do like the idea. There is one problem we'll need to solve. Let's tackle it separately. :)
I want to show that the function can operate on values of user-defined types. Does the confusion result from the fact that the List type is not described anywhere? |
29068ae
to
95695f9
Compare
var Function$prototype$chain = function(f) { | ||
var chain = this; | ||
return function(x) { return f(chain(x))(x); }; | ||
}; |
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.
Fortuitously, @buzzdecafe opened ramda/ramda#1936 today which alerted me to the fact that Function can satisfy the requirements of Chain. The implementation is straightforward. In fact, it's almost identical to that of Function$prototype$ap
since the only difference between the two functions is that one takes (a -> b -> c)
whereas the other takes (b -> a -> c)
.
95695f9
to
558b3da
Compare
|
||
//# toString :: a -> String | ||
//. | ||
//. Returns a useful string representation of its argument. |
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.
@Avaq pointed out that Z.toString(Object.create(null))
evaluates to '{}'
, so applying String
to the argument must not raise an exception was misleading. I've removed the warning and the Showable a
constraint. :)
I like this explanation :) And the TypeClass section also helps. Kind of just a problem the order the user sees the terms. Maybe a short glossary for terms like this that "value" could link to? Either way, not something to get hung up on at this point.
Reading this one again I think what you have is good. The word "method" is used prominently in the FL spec, I just hadn't read it in a while.
I see, I don't think I realized that (I like these examples more though knowing that!). Maybe a short sentence before these definitions to explain what |
558b3da
to
f4a1aa1
Compare
$seen.push(x); | ||
try { return method.call(x); } finally { $seen.pop(); } | ||
}; | ||
|
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.
Does this change look okay to you, @Avaq?
3ba300d
to
09e93ae
Compare
09e93ae
to
7804fa1
Compare
🎉 |
This pull request defines the following:
Z.TypeClass :: (String, Array TypeClass, a -> Boolean) -> TypeClass
Z.Setoid :: TypeClass
Z.Semigroup :: TypeClass
Z.Monoid :: TypeClass
Z.Functor :: TypeClass
Z.Bifunctor :: TypeClass
Z.Profunctor :: TypeClass
Z.Apply :: TypeClass
Z.Applicative :: TypeClass
Z.Chain :: TypeClass
Z.ChainRec :: TypeClass
Z.Monad :: TypeClass
Z.Foldable :: TypeClass
Z.Traversable :: TypeClass
Z.Extend :: TypeClass
Z.Comonad :: TypeClass
Z.toString :: Showable a => a -> String
Z.equals :: (a, b) -> Boolean
Z.concat :: Semigroup a => (a, a) -> a
Z.empty :: Monoid m => TypeRep m -> m
Z.map :: Functor f => (a -> b, f a) -> f b
Z.bimap :: Bifunctor f => (a -> b, c -> d, f a c) -> f b d
Z.promap :: Profunctor p => (a -> b, c -> d, p b c) -> p a d
Z.ap :: Apply f => (f (a -> b), f a) -> f b
Z.of :: Applicative f => (TypeRep f, a) -> f a
Z.chain :: Chain m => (a -> m b, m a) -> m b
Z.chainRec :: ChainRec m => (TypeRep m, (a -> c, b -> c, a) -> m c, a) -> m b
Z.filter :: (Applicative f, Foldable f, Monoid (f a)) => (a -> Boolean, f a) -> f a
Z.filterM :: (Monad m, Monoid (m a)) => (a -> Boolean, m a) -> m a
Z.reduce :: Foldable f => ((b, a) -> b, b, f a) -> b
Z.traverse :: (Applicative f, Traversable t) => (a -> f a, b -> f c, t b) -> f (t c)
Z.sequence :: (Applicative f, Traversable t) => (a -> f a, t (f b)) -> f (t b)
Z.extend :: Extend w => (w a -> b, w a) -> w b
Z.extract :: Comonad w => w a -> a
Original description: