11
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) ^

0__
  • 66,707
  • 21
  • 171
  • 266
Jas
  • 14,493
  • 27
  • 97
  • 148

3 Answers3

10

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__
  • 66,707
  • 21
  • 171
  • 266
  • question please in `isItCute` in main I pass an object of type `Cat`. The signature of `def isItCute[A: CuteChecker](a: A)` is receiving an `a` which it says is of type `[A: CuteChecker]` so it looks like it wants to receive a `CuteChecker` unless I don't understand what `A: Cutechecker` means. how can I receive a different type from `Cat`? i don't see i have any conversion between them all i have is an implicit CuteChecker for Cat – Jas Dec 26 '15 at 12:38
  • `def foo[A: Bar](x: A)` is syntactic sugar for `def foo[A](x: A)(implicit bar: Bar[A])`. If you want a `CuteChecker` for a type different than `Cat` you will have to define one and bring it into scope just like `CatCuteChecker`. – 0__ Dec 26 '15 at 19:25
0

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
}
Clashsoft
  • 11,553
  • 5
  • 40
  • 79
0

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.

Community
  • 1
  • 1
Daniel Mahler
  • 7,653
  • 5
  • 51
  • 90