origamitower / folktale

[not actively maintained!] A standard library for functional programming in JavaScript
https://folktale.origamitower.com/
MIT License
2.04k stars 102 forks source link

Adds Task.do #128

Closed framp closed 7 years ago

framp commented 7 years ago

As per issue #111. I've seen it's scheduled for post-2.0 but I had the code lying around and I love my (syntactic) sugar.

It can be used like this:

Task.do(function *() {
  const a = yield delay(10); 
  const b = yield delay(11); 
  const c = yield Task.of(5);
  return Task.of(a + b + c + 4);
})

Right now all the yielded / returned values need to be an instance of Task and behave like Haskell's bind, while in JavaScript (async/await, coroutines) values get promisified if they're not Promises.

I personally think it's confusing to promisify things implicitly and caused a few misunderstanding while teaching newcomers. What do you think about it?

EDIT: I forgot to say, I'm not sure I followed the right convention for the type annotation, so that may need some fixing

Thanks

robotlolita commented 7 years ago

Hey, thanks :)

I agree on the part of not trying to reify values into tasks implicitly. I do think this is better defined in terms of the Monad interface, though.

That way, given:

const  x = Task.do(function* () {
  const a = yield taskA;
  const b = yield taskB;
  return Task.of(a + b);
});

Gets translated to:

const x = taskA.chain(a => {
  return taskB.chain(b => {
    return Task.of(a + b);
  });
});

This ensures we respect things like external cancellation, which would be a bit more difficult doing this way because there's a bit of state that needs to be tracked.

framp commented 7 years ago

Sure thing, updated to use the monadic interface

robotlolita commented 7 years ago

Sorry for taking so long to review the changes Orz I'll try to do it this weekend

robotlolita commented 7 years ago

Thanksies :)