1
votes

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.

1
Works for me, but nevertheless you could move the implicits to NeoTypeEvidence's companion object and see if that helps.fotNelton
Is the thing in package.scala inside a package object that you forgot to mention?Iulian Dragos
Yes the trait and implicits were inside package object neoDylan

1 Answers

1
votes

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.