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

Alternative flatMap possible? #42

Open
alexandru opened this issue Feb 3, 2020 · 1 comment
Open

Alternative flatMap possible? #42

alexandru opened this issue Feb 3, 2020 · 1 comment

Comments

@alexandru
Copy link

alexandru commented Feb 3, 2020

Scala's "for comprehensions" first try to use withFilter and then fallback to filter if it doesn't exist.

I wonder if in a compiler plugin like this we could do the same thing for flatMap ... try a different a different name first, like flatMapT or something and if the type doesn't have it, then fallback to flatMap.


My problem is basically described here: https://contributors.scala-lang.org/t/proposal-for-opaque-type-aliases/2947/139

TL;DR — the flatMap on EitherT is:

// Does left widening
def flatMap[AA >: A, D](f: B => EitherT[F, AA, D])(implicit F: Monad[F]): EitherT[F, AA, D]

Which is basically different than the flatMap we get by implementing cats.FlatMap:

// No type widening
def flatMap[D](f: B => EitherT[F, A, D])(implicit F: Monad[F]): EitherT[F, A, D]

And if EitherT has an "opaque type" encoding, then these 2 signatures end up being in conflict and an explicit import cats.implicits._ will mask the first definition.

And giving that function a different name isn't a problem, we've got IDEs that help with the auto-completion, but in such a case the problem will be the for comprehensions, which in FP heavy code are ubiquitous.

@oleg-py
Copy link
Owner

oleg-py commented Feb 4, 2020

@alexandru Scala doesn't fallback to filter anymore:

I guess you could try to do what the PR did in reverse, kind of, but I'm actually not familiar with that machinery at all.

Alternatively, you can ditch cats.implicits._ in your project and have your own syntax object:

object appImplicits extends cats.syntax.AllSyntax /* with a ton of other traits */ {
  implicit def opsForEitherT[F, E, A](self: MyEitherT[F, E, A]): MyEitherT.Ops[F, E, A] = ???
}

this should work because your ops will take priority over inherited cats' ones.

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