'How exactly infix notation in custom extractors work?

In the example below, I have a ** object with apply and unapply methods. I am trying to understand how exactly the infix notation in the 2nd case works. I could not find anything that explains how the infix notation is de-sugared.

object ** {
  def apply[A, B](a: A, b: B) = (a, b)
  def unapply[A, B](p: (A, B)) = Some(p)

}

object CheckExtractor extends App {

  val v = **(1, "a")

  v match {
    case **(x, y) => println(s"extractor pattern 1: values $x and $y")
  }
  // extractor pattern 1: values 1 and a

  (v, 2) match {
    case x ** y ** z => println(s"extractor pattern 2: values $x and $y and $z")
  }
  // extractor pattern 2: values 1 and a and 2
}

For 2nd case statement, unapply is actually performed on ((1,"a"),2) which in turn returns Some((1,"a"),2). And I do not quite get how it is structurally equivalent to x ** y ** z, unless it translates to apply(apply(x,y),z) == ((x,y),z). but this is clearly not the case because the pattern works even if we take out the apply method



Solution 1:[1]

The pattern x ** y ** z expects to get Some((Some((A, B)), C)). It uses unapply of ** on the received value to match it. As it's nested, we have a call **.unapply((**.unapply(v), 2)) which returns Some((Some((1, "a")), 2)), which matches Some((Some((A, B)), C)).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ava