Skip to content
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

ap ordering is inconsistent #2172

Open
bkirwi opened this issue Feb 19, 2018 · 4 comments
Open

ap ordering is inconsistent #2172

bkirwi opened this issue Feb 19, 2018 · 4 comments

Comments

@bkirwi
Copy link
Contributor

bkirwi commented Feb 19, 2018

In Apply, ap is defined like so:

def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]

If we're using the generated typeclass syntax, that means user code looks like function.ap(value).

Unfortunately, when ap is explicitly defined, it's almost always defined the opposite way. For example, on Validated:

def ap[EE >: E, B](f: Validated[EE, A => B])

This gives us usage code like value.ap(function). Knowing which ordering to expect is pretty confusing: it varies depending on the data type involved and whether or not we're working with it in a generic context.

I guess since we're at 1.0 we probably can't just go and fix it, but we might be able to define an alias that's used more consistently. (ap has always felt like a bit of an odd name to me... cats usually sticks to full words for methods like this.) i have some preference for the second form: it keeps the function on the right like map and flatMap, and the type inference is better.

@ceedubs
Copy link
Contributor

ceedubs commented Mar 9, 2018

I agree this is inconsistent/confusing/unfortunate. There's some related discussion in #2074.

@bkirwi
Copy link
Contributor Author

bkirwi commented Mar 10, 2018

Ah, I see there's some history here! If this is a duplicate of an existing thing, we can maybe close?

I ran into this problem when trying to implement an applicative for comprehension -- that sort of syntactic abstraction relies on the same name meaning the ~same thing in different contexts, and would benefit from the improved type inference you get from putting the function on the right. That's a toy project, but those properties seem like they'd be more generally useful too.

@ceedubs
Copy link
Contributor

ceedubs commented Mar 11, 2018

@bkirwi the one that I linked is closed, so I think that we should keep this one open.

We used to have the function on the right and it caused lots of confusion because for a proper ap implementation the effect of the F[A => B] needs to be applied before the effect of the F[A]. There was a fair amount of discussion on this and we decided to change the order of the arguments to correspond to the effect ordering. I think that it's too late to go back on that decision. However, I do think that we should probably do something about the fact that the ordering is not always consistent. I'm just not sure what the best solution is :\

@bkirwi
Copy link
Contributor Author

bkirwi commented Mar 18, 2018

A nice incremental step might be to add the "ideal" signature as a new method / syntax extension, with the idea that we might switch in a future major release. My inclination would be to add to F[A] something like def applyMap[B](fn: F[A => B]): F[B], with left-to-right effect order. Does that seem plausible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants