Dylan
Dylan

Reputation: 13859

Scala finds my implicit conversion twice, causing "ambiguous implicit" errors

I'm playing around with a third party library that has a PropertyContainer interface. It lets you get/set properties in terms of java.lang.Object, but it really only supports java primitives, strings, and arrays of those things. So I'm trying to make a light wrapper over the property container class.

Property.scala

class Property[A <% NeoTypeEvidence[A]](val name: String) {
  def apply(pc: PropertyContainer) = pc.getProperty(name).asInstanceOf[A]
  def update(pc: PropertyContainer, value: A) = pc.setProperty(name, value)
}

package.scala

{
  sealed trait NeoTypeEvidence[A]
  object AnyValTypeEvidence extends NeoTypeEvidence[AnyVal]
  object StringTypeEvidence extends NeoTypeEvidence[String]
  object AnyValArrayTypeEvidence extends NeoTypeEvidence[Array[AnyVal]]
  object StringArrayTypeEvidence extends NeoTypeEvidence[Array[String]]

  implicit def anyValToEvidence(v: AnyVal) = AnyValTypeEvidence
  implicit def stringToEvidence(s: String) = StringTypeEvidence
  implicit def anyValArrayToEvidence(v: Array[AnyVal]) = AnyValArrayTypeEvidence
  implicit def stringArrayToEvidence(s: Array[String]) = StringArrayTypeEvidence
}

test file

val name = new Property[String]("name")

I would expect that to work just fine, assuming that the compiler finds the implicit StringTypeEvidence to satisfy the condition of [String <% NeoTypeEvidence[String]]. What I get instead is an error:

ambiguous implicit values:  
both method stringToEvidence in package neo of type 
  (s: String) com.dylemma.neo.package.StringTypeEvidence.type  
 and method stringToEvidence in package neo of type 
  (s: String) com.dylemma.neo.package.StringTypeEvidence.type  
match expected type 
String => com.dylemma.neo.package.NeoTypeEvidence[String]

So scala is finding my implicit conversion twice?? I've done a clean+rebuild several times but that hasn't fixed anything. Why is this happening and how can I fix it?

edit/note: I notice that this only seems to happen when I try to create a Property in the same package as where the implicits were defined. So if I do the exact same code in some.other.package and have an import for the.main.package._, it works without complaint. I still don't understand why, though.

Upvotes: 1

Views: 448

Answers (1)

Daniel Langdon
Daniel Langdon

Reputation: 5999

My guess is that you are importing the implicit twice. Check the rules for implicit resolution here.

Most likely (albeit hard to say with your sample), you are using an explicit import while also working on the same package, where the implicit is already present by default.

Upvotes: 1

Related Questions