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

Popular posts from this blog

javascript - how to protect a flash video from refresh? -

android - Associate same looper with different threads -

visual studio 2010 - Connect to informix database windows form application -