briancavalier / creed

Sophisticated and functionally-minded async with advanced features: coroutines, promises, ES2015 iterables, fantasy-land
https://briancavalier.github.io/creed
MIT License
273 stars 20 forks source link

Add Alt, Plus, Alternative #92

Closed briancavalier closed 7 years ago

briancavalier commented 7 years ago

Add FL 2.1 implementations and tests: Alt, Plus, Alternative. The implementations are trivial--they're rally just aliases for or and never. This means that for 1.x, Monoid and Alt are basically the same thing. For 2.0, we can implement a value-based Monoid.

I found that the fantasyland-laws tests were wrong: they were not calling the laws correctly. The laws are manually curried, and we were calling them with multiple args, so the tests weren't actually verifying anything useful O.o. Mocha was no help, since it's perfectly content to let you write tests with no assertions even when they return something other than a promise. That's also why nyc/istanbul wasn't counting coverage: because the tests weren't really calling any creed code. Fun, eh?

coveralls commented 7 years ago

Coverage Status

Coverage remained the same at 100.0% when pulling 687f9ef0e14efb1ac1c2f7be18296e35ccd7fc6e on add-fl-alt-plus into 458d79041f557e19a07f0ef1d77e2db3fa173d57 on master.

davidchase commented 7 years ago

👍 LGTM

safareli commented 7 years ago

I think this is not quite valid instance for Monadic Promise see https://github.com/fantasyland/fantasy-land/issues/203

briancavalier commented 7 years ago

@safareli I debated whether parallel or left catch was the correct Alternative instance, and honestly, I'm still not sure. Your comment from fantasyland/fantasy-land#203, though, seems like it might be the most practical reason to pick left catch:

in right branch, function from both f or g will be called

I had been thinking the same as you, though, that it doesn't matter from the standpoint of the laws (though it is wasteful), as long as g is pure.

@jdegoes later comment makes me think there has to be another reason that I'm not seeing. Can you help me understand it a bit better before I go down the path of changing it? Thanks!

safareli commented 7 years ago

I think, if you have both monadic and non monadic version of Future, in monadic one you should be have sequential Alternative instance and in non monadic one parallel, but don't know if there is any law which restricts to not make monadic one with parallel Alternative instance. maybe @jdegoes can help, but general intuition is that if structure is a Monad it should be sequential.

briancavalier commented 7 years ago

@safareli Yes, I had the same general intuition (Monad should imply sequential). However, in the course of trying to figure out which way to go with this PR, I ran into the discussions around Haskell's MonadOr and MonadPlus debate. The gist is that there are some monads where Left Distribution is more natural and some where Left Catch is more natural. Additionally, there may even be some monads where both are feasible. And at least so far, both do seem reasonable to me for promises.

Do you or @jdegoes have any thoughts on the Haskell MonadOr/MonadPlus situation? Is it possible that Fantasy Land will explore a direction like Haskell to allow for both?

jdegoes commented 7 years ago

I agree the distinction is useful, and I think you could implement parallel left catch semantics for a monad without breaking any laws. Both seem reasonable for a future.