oleg-py/better-monadic-for

Final `map` is not eliminated for an abstract F

Closed this issue · 4 comments

The problem is easy to reproduce:

import $plugin.$ivy.`com.olegpy::better-monadic-for:0.2.4`
import $ivy.`org.typelevel::cats-core:1.4.0`

import cats._
import cats.instances.option._
import cats.syntax.applicative._

for {
  a <- 1.pure[Option]
} yield a
//Works well

def proc[F[_]: Monad, T](x: T): F[T] =
  for {
    a <- x.pure[F]
  } yield a
// value map is not a member of type parameter F[T]

Plugin doesn't remove the map if it is the only thing in a for-comprehension. The first sample works, because there's map on option, for the second one you don't have the syntax import for functor.

A more complex example with flatMap doesn't work as well:

import $plugin.$ivy.`com.olegpy::better-monadic-for:0.2.4`
import $ivy.`org.typelevel::cats-core:1.4.0`

import cats._
import cats.instances.option._
import cats.syntax.applicative._
import cats.syntax.flatMap._

for {
  _ <- 1.pure[Option]
  b <- 2.pure[Option]
} yield b
//Works well

def proc[F[_]: Monad, T](x: T, y: T): F[T] =
  for {
    _ <- x.pure[F]
    b <- y.pure[F]
  } yield b
// value map is not a member of type parameter F[T]

@danslapman the map optimization is done after typer, so the code must be compile-able first.

Okay, got it