scalaimplicitshapelesspartially-applied-type

Implicit not found for partially applied type


While this problem was caught in code using shapeless and kind-projector, this behavior could be reproduced without them.

Suppose I have simple typeclass for reifying typeclass instances with incomplete implementation (mirror of LiftAll).

sealed trait LiftAll1[F[_], In] {
  type Out
  def instances: Out
}

object LiftAll1 {
  type Aux[F[_], In0, Out0] = LiftAll1[F, In0] {type Out = Out0}
  implicit def unit[F[_]]: Aux[F, Unit, Unit] = new LiftAll1[F, Unit] {
    type Out = Unit
    def instances = Unit
  }
}

And some very simple type class to test it

sealed class FirstIs[M, T]
object FirstIs {
  implicit def firstIs[M, D]: FirstIs[M, (M, D)] = new FirstIs
}

Things are ok if I'll try to apply FirstIs partially via alias, and get instance via LiftAll1

type FirstIsInt[D] = FirstIs[Int, D]
implicitly[LiftAll1[FirstIsInt, Unit]]

But inlined partial type application leads to compilation error

implicitly[LiftAll1[({type lambda[x] = FirstIs[Int, x]})#lambda, Unit]]
//Error: could not find implicit value for parameter e: LiftAll1[[x]FirstIs[Int,x],Unit]

How partially applied typeclasses could be found in such situations?


Solution

  • As @Reactormonk suggested, the compiler was brought to its senses with following line in the build.sbt

    scalacOptions += "-Ypartial-unification"
    

    After that original piece of code, which is close to

    import shapeless._, ops.hlist._
    
    LiftAll[FirstIs[Int, ?], HNil]
    

    was succesfully compiled

    AFAIK problem was in scala compiler incapability to understand FirstIs[Int,_] as F[_]in supplied implicit def without direct type alias . Fortunately this was fixed in latest scala implementations.