Comments (30)
They're all specific cases of a more general Semigroupoid idea.
I recall you and @scott-christopher discussing that in the gitter room. i may take a whack at unifying our many composers into one.
Which raises the thought: A good name for a javascript composition lib would be Bach.js
from sanctuary.
Oh, duh. 🐐
The only limitation I see here is that this form of do
notation only really allows you to feed through a single monadic value. You lose the ability to bind different variables to different monadic values in the same do expression like the following example:
foo :: Maybe String
foo = do
x <- Just 3
y <- Just "!"
Just (show x ++ y)
from sanctuary.
wow, that is nice sugar. FWIW, I think $do
is fine
from sanctuary.
wow, that is nice sugar.
I think so too! Shall I open this for discussion on the Ramda issue tracker? The function could be defined there instead. :)
from sanctuary.
your call. looks pretty interesting to me.
Can't you also do this:
// $do :: Monad m => [(a -> m b), (b -> m c), ..., (y -> m z)] -> m a -> m z
const $do = R.apply(R.pipe, R.map(R.chain));
?
It also seems like there is a way to write this with ap
, but don't have time to prove that right now
from sanctuary.
The types don't line up in your definition, @buzzdecafe. You're fully applying (ahem) R.apply
(which takes two arguments).
from sanctuary.
Why isn't do a valid identifier?
from sanctuary.
do
is a keyword: do...while
.
from sanctuary.
yep, i was reading apply
like compose
for some reason
from sanctuary.
The only limitation I see here is that this form of
do
notation only really allows you to feed through a single monadic value.
True. R.compose
and R.pipe
share this limitation, of course.
from sanctuary.
R.compose and R.pipe share this limitation, of course.
I don't really see how that relates. I think you might be able to come up with a way to bind different variables but I'm guessing it would be pretty hacky.
I think this is cool for the single pipeline case though!
from sanctuary.
I think you might be able to come up with a way to bind different variables but I'm guessing it would be pretty hacky.
indeed. I was trying to come up with some way to do that, but all i could come up with could only generously be called "hacky"
from sanctuary.
Does
do
go by other names?
The name you're looking for is Kleisli
: https://en.wikipedia.org/wiki/Kleisli_category
What you've Greenspun'd is exactly Kleisli composition. :)
from sanctuary.
The name you're looking for is
Kleisli
It sounds as though Ramda needs more composition functions. R.composeK
and R.pipeK
, anyone?
from sanctuary.
😱
from sanctuary.
Sorry, I didn't actually look close enough. $do
isn't entirely kleisli composition. If you have:
// kleisli : Chain m => [a -> m b, b -> m c, ..., y -> m z] -> a -> m z
Then yes.
Also, note that you don't actually need the full power of Monad
for this.
from sanctuary.
It sounds as though Ramda needs more composition functions.
R.composeK
andR.pipeK
, anyone?
No, it definitely needs less (ideally one). They're all specific cases of a more general Semigroupoid
idea.
from sanctuary.
@joneshf, do you think such a function should return a -> m z
rather than m a -> m z
?
I'm having a bit of trouble seeing how something of the shape
R.pipe(
S.Just,
R.chain(f),
R.chain(g),
R.chain(h),
R.chain(i),
R.chain(j)
);
can be rewritten as a pipeline where every function in the pipeline is a partially applied R.chain
.
from sanctuary.
@joneshf, do you think such a function should return
a -> m z
rather thanm a -> m z
?
I was just nitpicking, and looking more closely at the haskell stuff.
They're equivalent, so either way is fine, since (f >=> g) x = f x >>= g
and x >>= f = (id >=> f) x
. So choose either one and you can provide the other easily.
I'm having a bit of trouble seeing how something of the shape
...
can be rewritten as a pipeline where every function in the pipeline is a partially appliedR.chain
.
Hmm, I think I'm having a brain fart here, or I'm not understanding the question.
from sanctuary.
They're equivalent, so […] choose either one and you can provide the other easily.
That makes sense. :)
I think I'm having a brain fart here, or I'm not understanding the question.
I didn't see at the time how to return a -> m z
rather than m a -> m z
. I do now. The implementation is a bit more involved, since one must apply R.chain
to all the arguments but the first:
// $do :: Chain m => [(a -> m b), (b -> m c), ..., (y -> m z)] -> a -> m z
const $do = R.pipe(R.converge(R.prepend,
R.head,
R.pipe(R.tail, R.map(R.chain))),
R.apply(R.pipe));
[Ramda's various composition functions and the proposed Kleisli composition functions are] all specific cases of a more general
Semigroupoid
idea.
I'm intrigued by the possibility of a composition function which can perform Kleisli composition as well as "regular" function composition. I've no idea how this is possible. :)
from sanctuary.
Thinking about it now, I think the only way to make it happen is to wrap the monadic function in a Kleisli
type.
from sanctuary.
Also, if it wasn't clear from the signature Kleisli == ReaderT
, and a -> b == ReaderT Identity a b
. So that's why I feel these can be unified. But I think without a compiler implicitly passing around things and wrapping/unwrapping, it'd end up being a less than optimal api.
from sanctuary.
But I think without a compiler implicitly passing around things and wrapping/unwrapping, it'd end up being a less than optimal api.
That's often where the rubber meets the road with JS libs. There a lot of 'almost's and 'if only's floating around, usually having to do with its type system.
from sanctuary.
Thinking about it more, you'd run into the same api issues in haskell. And the ways around it are just as suboptimal, but for different reasons. I guess I just want too much.
from sanctuary.
ramda/ramda#1212 added a variadic version of the proposed $do
function as R.pipeK
.
from sanctuary.
@davidchambers, any interest in revisiting this now that Sanctuary is no longer dependent on Ramda?
from sanctuary.
Absolutely! Let's open a new issue: pipeK
is more limited than Haskell's do
notation because it doesn't provide access to the results of all previous computations. Would you mind opening an issue for pipeK
, @gabejohnson?
from sanctuary.
I can do that.
I've also been looking at arrows and categories. Seems like something that would be useful to add to the spec.
from sanctuary.
Looks like there's already an issue for it fantasyland/fantasy-land#208
from sanctuary.
See #380
from sanctuary.
Related Issues (20)
- Possible example bug HOT 3
- How to create a function in 'sanctuary'? HOT 2
- State and Reader ADTs
- ES5 => ES6 HOT 1
- Bundled version contains refetences to undefined self HOT 4
- Add "picks" to include certain key/value pairs from an object HOT 3
- Deno version HOT 2
- Add a function to split an Array into equally sized chunks
- Idea: Only treat objects without prototypes as StrMaps HOT 6
- Be more explicit about S.get(s) being an escape hatch from type safety HOT 1
- Question about S.concat HOT 4
- Support logging S.Nothing in deno
- feat: Make types accessible by name in `S` HOT 1
- Remove the need for require ('util') in browser environment HOT 4
- Check for empty structures? HOT 1
- Searchbar on website https://sanctuary.js.org/ HOT 1
- Implement Types for all new EcmaScript objects.
- match has changed from version 3.1.0 HOT 2
- Refactor documentation to be more independent and catchy
- ECMAScript modules HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sanctuary.