David Portabella
David Portabella

Reputation: 12720

scala, adding an implicit function to the Map class, fails with "structural refinement may not refer to an abstract"

  import scala.language.implicitConversions

  implicit def extendedMap[A,B](map: Map[A,B]) = new {
    def updatedOption(key: A, valueOption: Option[B]) = valueOption match {
      case Some(value) => map.updated(key, value)
      case None => map - key
    }
  }

  var kv = Map.empty[String, String]
  kv.updatedOption("k1", Some("v1")

  //removing the implicit keyword, and explicitly calling the conversion also fails:
  extendedMap(kv).updatedOption("k1", Some("v1")

error compiler message:

Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
    def updatedOption(key: A, valueOption: Option[B]) = valueOption match {

                  ^

how to solve it?

Upvotes: 1

Views: 87

Answers (1)

senia
senia

Reputation: 38045

Since scala 2.10 you should not use implicit def for extension methods - use implicit class instead. See SIP-13. With implicit class you should not import language.implicitConversions:

implicit class ExtendedMap[A,B](map: Map[A,B]) {
  def updatedOption(k: A, v: Option[B]) = v.map{ map.updated(k, _) }.getOrElse(map - k)
}

Actually it should work with implicit def with explicit class declaration like this:

class ExtendedMap[A,B](map: Map[A,B]) {
  def updatedOption(k: A, v: Option[B]) = v.map{ map.updated(k, _) }.getOrElse(map - k)
}
implicit def toExtendedMap[A,B](map: Map[A,B]): ExtendedMap[A,B] =
  new ExtendedMap[A, B](map)

Upvotes: 2

Related Questions