Closed ethul closed 9 years ago
While playing with this I realized that PromiseEff
has kind of unexpected semantics: because of the way thenEffFn
is defined, any binding of a PromiseEff
immediately runs the effect, rather than resulting in a new composed effect. That is, p >>= pure
is equivalent (in effect and type) to promiseEff (unsafeRunPromiseEff p)
. I'm not sure whether this was intentional, but it seems confusing: a PromiseEff
runs the effect as soon as the promise resolves, only if something was done with the result.
I'm not sure it's possible to write thenEffFn
in the expected way because using b -> PromiseEff e f a c
simultaneously needs to immediately obtain the promise for angular, and not actually provide b
until the effect is evaluated.
All this makes me wonder if trying to expose a promise interface is really the right approach. Maybe it would make more sense to immediately convert the promises to ContT
or something and work with them that way. Alternatively, Promises (like event Handler
) could just always contain and execute effects on resolution (making Promise
a special case of PromiseEff
rather than the other way around).
I think you make a good point. Perhaps simplifying the promise represention is the way to go. I kind of think that it would be good to maintain the API of promises; i.e., just having the functions then
, catch
, finally
and removing pureResolve
, pureReject
, PromiseEff
, and the typeclass instances.
And then, as you suggest, provide a way to convert a promise to ContT
. It might be nice if the user had the option to use the functions like then
, or go the ContT
route. This way it's up to them.
I just took a quick look, but it could be similar to how purescript-json-ajax works. I can spend more time on this over the weekend, but if you have anything started on this, it would be great to collaborate.
Also, I am open to your second proposal of making promises a special case of PromiseEff
, but I am sort of leaning toward ContT
since I think it might simplify the library code. But if you have any other ideas on this, I am up for discussing further.
I don't have much yet but just exploring some options (currently with terrible names). One problem with leaving promises behind is making sure the angular digest cycle gets invoked (which perhaps could be solved by making a custom ContT
that wraps continuations in $apply
calls). Leaving the vanilla Promise API does seem reasonable.
I did have an unrelated simpler idea for eliminating pureResolve
which I'll put on #20.
I think your code is looking good. Good point about the digest. In order to wrap the continuation in $apply
we'd have to include a $scope
in the mix.
Just to put another idea on the table, I suppose the bare-bones option would be to only provide the vanilla Promise
API and nothing else. In this case, custom ContT
implementations or new data types could live in add-on libs.
I am not suggesting we should go this route; because frankly, I am not sure what the best option is. However, we could decide that purescript-angular
is just a direct mapping of AngularJS to PureScript. Or maybe not. Still unsure.
Closing this for now as #23 has been merged. We can reopen or continue discussion on a new issue if we want to brainstorm on this topic again.
PromiseEff e e a b -> Eff e (Promise a b)