The question is why doesn't the following code work with type inference (below is a REPL session to demonstrate), and can it be fixed? More specifically, how is this different from the use of CanBuildFrom which the compiler uses to infer the return type?
Given this code:
object S {
import java.net._
trait UrlLike[T] {
def url(s: String): T
}
object UrlLike {
implicit object str extends UrlLike[String]{def url(s: String) = s}
implicit object url extends UrlLike[URL]{def url(s: String) = new URL(s)}
implicit object uri extends UrlLike[URI]{def url(s: String) = new URI(s)}
}
trait UrlSupport {
val _url: String
def url[T : UrlLike]: T = implicitly[UrlLike[T]].url(_url)
}
}
I have this session in the REPL (2.8.1):
scala> :load c:\temp\UrlTest.scala
Loading c:\temp\UrlTest.scala...
defined module S
scala> import java.net._
import java.net._
scala> import S._
import S._
scala> new UrlSupport{val _url = "http://example.com"}
res0: java.lang.Object with S.UrlSupport = $anon$1@155bd22
scala> res0.url : String
<console>:14: error: ambiguous implicit values:
both object uri in object UrlLike of type object S.UrlLike.uri
and object url in object UrlLike of type object S.UrlLike.url
match expected type S.UrlLike[T]
res0.url : String
^
scala> res0.url : URL
<console>:14: error: ambiguous implicit values:
both object uri in object UrlLike of type object S.UrlLike.uri
and object url in object UrlLike of type object S.UrlLike.url
match expected type S.UrlLike[T]
res0.url : URL
^
scala> res0.url[String]
res3: String = http://example.com
scala> res0.url[URL]
res4: java.net.URL = http://example.com
> trait UrlLike[T] {
trait UrlLike[+T] {