-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
FreeApplicative applies effects in wrong order #799
Comments
Hmm this might actually be because of how |
Wouldn't it be due to the way Const Applicative |
@mandubian I am pretty sure |
not yet in master, right? |
@mandubian It should be. It was merged with #502 I believe. |
oh no, you mean it's normal to be in the opposite and it's right in master :)
I've added some dummy println to check order:
So it seems to execute as expected... |
I don't really understand why we have made this modification for
and in cats it's
so f & fa should have been reversed not the order of execution of f & fa... and in haskell it is clearly considered that order of execution in an applicative has been chosen from left to right (even if in theory, there is no order, it should just be deterministic) |
@mandubian I think the important thing is that the effect of the |
I've looked at Haskell Const applicative and yes it seems to apply function before... |
I ran into this issue today with: https://github.com/adelbertc/cats/blob/monoidal-redux/laws/src/main/scala/cats/laws/ApplicativeLaws.scala#L36 My initial impression was to do: F.ap(fa)(f) <-> F.map(F.product(fa, f)) { case (a, f) => f(a) } but had to change to this to account for the evaluation of effects of F.ap(fa)(f) <-> F.map(F.product(f, fa)) { case (f, a) => f(a) } |
Just as a side note, the free applicative implementation of purescript had this issue too: ethul/purescript-freeap#4 |
@adelbertc it seems to be implemented as is if I'm not wrong... you write |
@LiamGoodacre thanks for the reference, that's helpful! @mandubian yes, in I've changed the following line of the case Ap(pivot, fn) => G.ap(f(pivot))(fn.foldMap(f)) to this: case Ap(pivot, fn) => G.map2(f(pivot), fn.foldMap(f))((a, g) => g(a)) This seems to fix the issue. There may be a more elegant or efficient way of writing this. Should I go ahead and submit a PR for this? |
my problem for now is that it's completely error prone... nobody will remind that when calling ap(a)(f), f is executed before a... and map2 does it in the left to right way... |
@mandubian that's a fair concern. Should we change the signature of I do think that's a separate issue from this one, though. I'm inclined to address each in different PRs. |
Here is a fairly minimal way to reproduce the error:
I believe this is a bug in the
ap
implementation.Scalaz's implementation of
FreeAp
does the same thing, so it's possible that I'm wrong about what the expected result should be, but I don't think so. cc @runarorama@adelbertc, @mandubian, or @raulraja would any of you want to take a look at this by any chance?
The text was updated successfully, but these errors were encountered: