scalafunctorhigher-kinded-typestype-projection

Compilation error when declaring Functor for Either even after using type projections


I am trying to write a Functor for Either for academic purposes in Scala. With help of higher-kinded types and type-projections, I managed to write an implementation for Either.

trait Functor[F[_]] {
  def map[A, B](fa: F[A])(f: A => B): F[B]
}

object Functor {
  implicit def eitherFunctor[A] = new Functor[({type λ[α] = Either[A, α]})#λ] {
    override def map[B, C](fa: Either[A, B])(f: B => C) = fa.map(f)
  }
}

def mapAll[F[_], A, B](fa: F[A])(f: A => B)(implicit fe: Functor[F]): F[B] = fe.map(fa)(f)

val right: Either[String, Int] =  Right(2)

mapAll(right)(_ + 2)

Now, the code above does not compile. I am not sure of the reason but the compilation error that I am getting is given below -

Error:(19, 16) type mismatch;
 found   : Either[String,Int]
 required: ?F[?A]
Note that implicit conversions are not applicable because they are ambiguous:
 both method ArrowAssoc in object Predef of type [A](self: A)ArrowAssoc[A]
 and method Ensuring in object Predef of type [A](self: A)Ensuring[A]
 are possible conversion functions from Either[String,Int] to ?F[?A]
  mapAll(right)(_ + 2)

Can someone point what I am not doing right in the code above?

PS: Please do not suggest me to use kind-projector.


Solution

  • You've just been bitten by SI-2712. If you're using Scala >= 2.12.2 just add this line to your build.sbt:

    scalacOptions += "-Ypartial-unification"
    

    For other Scala versions you can use this plugin.