Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - implicit conversion with unapply

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.

like image 663
dhg Avatar asked Jul 18 '11 17:07

dhg


People also ask

What is an implicit conversion function in Scala?

Implicit conversions in Scala are the set of methods that are apply when an object of wrong type is used. It allows the compiler to automatically convert of one type to another. Implicit conversions are applied in two conditions: First, if an expression of type A and S does not match to the expected expression type B.

What is the use of apply and Unapply in Scala?

Whereas the apply method is like a constructor which takes arguments and creates an object, the unapply takes an object and tries to give back the arguments. This is most often used in pattern matching and partial functions. The apply method creates a CustomerID string from a name .

What is implicit class in Scala?

Scala 2.10 introduced a new feature called implicit classes. An implicit class is a class marked with the implicit keyword. This keyword makes the class's primary constructor available for implicit conversions when the class is in scope. Implicit classes were proposed in SIP-13.

What is implicit request?

With implicit request It allows to get an instance of Messages automatically (the compiler will implicitly call request2Messages(yourRequest) when needed but you need to have an implicit request (or request header) in scope.


1 Answers

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)
}
like image 196
Jean-Philippe Pellet Avatar answered Oct 11 '22 15:10

Jean-Philippe Pellet