I'd like an extractor to implicitly convert its parameters, but it doesn't seem to work. Consider this very simple case:
case class MyString(s: String) {}
implicit def string2mystring(x: String): MyString = new MyString(x)
implicit def mystring2string(x: MyString) = x.s
object Apply {
def unapply(s: MyString): Option[String] = Some(s)
}
But I'm not able to use it as I would expect:
val Apply(z) = "a" // error: scrutinee is incompatible with pattern type
Can anyone explain why it fails to convert the parameter from String
to MyString
? I would expect it to call string2mystring("a")
on the fly. Clearly I could work around the issue by saying val Apply(y) = MyString("a")
, but it doesn't seem like I should have to do that.
Note: This question is similar to this one, but 1) that one doesn't really have a good answer for why this is happening, 2) the example is more complex than it needs to be.
Implicit conversions are not applied when pattern matching. That's not a bug or a problem with your code, it's simply a design decision of the creators of Scala.
To fix it, you should write another extractor that accepts a String
— which in turn can call your implicit conversion.
Alternatively, you can try with a view bound, which seems to work as well, and will also work if you later define other implicit conversions to MyString
:
object Apply {
def unapply[S <% MyString](s: S): Option[String] = Some(s.s)
}