could not find implicit value for parameter e
Asked Answered
B

3

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

Booth answered 25/12, 2015 at 20:35 Comment(0)
T
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"))
}
Tryma answered 25/12, 2015 at 20:46 Comment(2)
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 CatBooth
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.Tryma
N
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
}
Nara answered 25/12, 2015 at 20:44 Comment(0)
C
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://mcmap.net/q/80576/-where-does-scala-look-for-implicits.

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.

Coben answered 25/12, 2015 at 23:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.