scala - Creating instances of a covariant type class from instances of a non-covariant one -
suppose i've got simple type class instances give me value of type:
trait givemejusta[x] { def apply(): x }
and i've got instances:
case class foo(s: string) case class bar(i: int) implicit object givemejustafoo extends givemejusta[foo] { def apply() = foo("foo") } implicit object givemejustabar extends givemejusta[bar] { def apply() = bar(13) }
now have similar (but unrelated) type class same thing covariant in type parameter:
trait givemea[+x] { def apply(): x }
in companion object tell compiler how create instances instances of our non-covariant type class:
object givemea { implicit def fromgivemejusta[x](implicit giveme: givemejusta[x]): givemea[x] = new givemea[x] { def apply() = giveme() } }
now i'd expect implicitly[givemea[foo]]
compile fine, since there's 1 way givemea[foo]
given pieces have here. doesn't (at least not on either 2.10.4 or 2.11.2):
scala> implicitly[givemea[foo]] <console>:16: this.givemea.fromgivemejusta not valid implicit value givemea[foo] because: hasmatchingsymbol reported error: ambiguous implicit values: both object givemejustafoo of type givemejustafoo.type , object givemejustabar of type givemejustabar.type match expected type givemejusta[x] implicitly[givemea[foo]] ^ <console>:16: error: not find implicit value parameter e: givemea[foo] implicitly[givemea[foo]] ^
if rid of our irrelevant givemejusta
instance, works:
scala> implicit def givemejustabar: list[long] = ??? givemejustabar: list[long] scala> implicitly[givemea[foo]] res1: givemea[foo] = givemea$$anon$1@2a4f2dcc
this in spite of fact there's no way can apply givemea.fromgivemejusta
instance givemea[foo]
(or subtype of givemea[foo]
).
this looks bug me, it's possible i'm missing something. make sense? there reasonable workaround?
i not understand why working, following code resolves implicit in current case (at least on scala v-2.10.1). however, still not explains why example not working in first place:
we change implicit givemea[x]
instance search implicit givemejusta
instances type parameter bounded upwards x
, searches givemejusta[_ <: x]
object givemea { implicit def fromgivemejusta[x](implicit giveme: givemejusta[_ <: x]) : givemea[x] = new givemea[x] { def apply() = giveme() } }
we can print out expected output
val = implicitly[givemea[foo]] println(a()) // prints "foo(foo)"
however, introduce new subclass
case class foochild(s: string) extends foo(s)
and respective givemejusta
typeclass instance
implicit object givemejustafoochild extends givemejusta[foochild] { def apply() = foochild("foochild") }
the compiler complains (as expected)
error: not find implicit value parameter e: givemea[foo] val = implicitly[givemea[foo]]
Comments
Post a Comment