10
votes
case class Cat(name: String)

object CuterImplicits {
  implicit class CatCuteChecker(c: Cat) {
    def isCute(c: Cat) = true
  }
}

trait CuteChecker[A] {
  def isCute(a: A): Boolean
}

object CheckingForCuteness {
  def isItCute[A](a: A) = implicitly[CuteChecker[A]].isCute(a)
}

object Main extends App {
  CheckingForCuteness.isItCute[Cat](Cat("funny"))
}

how to fix:

Error:(17, 37) could not find implicit value for parameter e: CuteChecker[A] def isItCute[A](a: A) = implicitly[CuteChecker[A]].isCute(a) ^

3

3 Answers

10
votes

If you use implicitly that simply makes a value implicitly in scope "explicitly" available. So your isItCute method should be either of the following two variants:

def isItCute[A: CuteChecker](a: A) = implicitly[CuteChecker[A]].isCute(a)

def isItCute[A](a: A)(implicit cc: CuteChecker[A]) = cc.isCute(a)

Next you want an implicit instance for Cat. The implicit class doesn't help you here because it requires a non-implicit value of type Cat. You can see that this approach is wrong because the constructor parameter is never used. You can use an implicit object:

implicit object CatCuteChecker extends CuteChecker[Cat] {
  def isCute(c: Cat) = true
}

Finally, you provide implicits in object CuterImplicits. For them to be visible to Main, you need to import the contents:

object Main extends App {
  import CuterImplicits._
  CheckingForCuteness.isItCute[Cat](Cat("funny"))
}
0
votes

There a multiple problems in your situation. The implicitly call expects an instance of the CuteChecker trait, while CatCuteChecker is neither an instance nor does not it extend this trait. Furthermore, the c class parameter is completely unnecessary.

You can fix your problem by declaring that subtyping relationship and providing an implicit value:

object CuterImplicits
{
    class CatCuteChecker with CuteChecker
    {
        def isCute(c: Cat) = true
    }

    implicit val catCuteChecker = new CatCuteChecker
}
0
votes

Implicits have to be visible unqualified at the point of invocation. Different ways that implicits can become visible is best described in this answer: https://stackoverflow.com/a/5598107/843348.

It is also not completely clear what you are trying to achieve and there are a number of possible ways to achieve something like the example.

One possibility is monkey patching Cat using an implicit class:

case class Cat(name: String)

object CuteImplicits {
  implicit class CuteCat(c: Cat){
    def isCute = true
  }
}

object Main extends App {
  import CuteImplicits._
  Cat("funny").isCute
}

You put implicits in the companion object of an associated type and the it is visible automatically.

case class Cat(name: String)

object Cat {
  implicit class CuteCat(c: Cat){
    def isCute = true
  }
}

object Main extends App {
  Cat("funny").isCute
}

In minimal example like this it not clear why you would not build the functionality directly into Cat.