Abdul Rahman Abdul Rahman - 20 days ago 8
Scala Question

Unable to find implicit value

So my code looks as follows

package typeclasses

trait Eq[T]{

def == (t1: T, t2: T) : Boolean
}

case class MyClass()

object MyClass {

implicit object EqMyClass extends Eq[MyClass] {
override def ==(t1: MyClass, t2: MyClass): Boolean = true
}
}

object App1 extends App{

import Tree._
import MyClass._

def equality[T](t1: T, t2: T)(implicit eq: Eq[T]): Boolean = eq.==(t1, t2)

//println(equality(Node(1), Node(2)))

println(equality(MyClass, MyClass))
}


However I get the error that compiler is unable to find implicit value for Eq[MyClass]. Here is the error that I get.

Error:(38, 19) could not find implicit value for parameter eq: typeclasses.Eq[typeclasses.MyClass.type]
println(equality(MyClass, MyClass))


Shouldn't it have found Eq[MyClass] since I import the MyClass object into App1 and have EqMyClass defined in there? Also do I even need to import MyClass object into App1? My understanding was that scala looks at companion objects of arg types to find implicit defs?

Thanks!

[Edit]

So the original error is resolved. Now I am trying to do similar for my polymorphic Tree class. My code is as follows. It works but was wondering if the way I define EqTree can be simplified?

sealed trait Tree[+A]
final case class Node[A](value: A) extends Tree[A]
final case class Branch[A](value: A, left: Tree[A], right: Tree[A]) extends Tree[A]

object Tree{

implicit def eqTree[A[T] <: Tree[T], T]: Eq[A[T]] = new Eq[A[T]] {
override def ==(t1: A[T], t2: A[T]): Boolean = true
}
}


If I define eqTree as

object Tree{

implicit def eqTree[T]: Eq[Tree[T]] = new Eq[Tree[T]] {
override def ==(t1: Tree[T], t2: Tree[T]): Boolean = true
}
}


Then if I do

object App1 extends App{

import Tree._

def equality[T, T1<: T, T2 <: T](t1: T1, t2: T2)(implicit eq: Eq[T]): Boolean = eq.==(t1, t2)

println(equality(Node(1), Node(2)))
}


I get the following error

Error:(35, 19) could not find implicit value for parameter eq: typeclasses.Eq[typeclasses.Node[Int]]
println(equality(Node(1), Node(2)))
^


Thanks!

Answer

you have to write println(equality(MyClass(), MyClass()) since MyClass is the companion object (of type MyClass.type) instead of an instance of MyClass.