title: Scala: Pattern matching when one of two items meets some condition
body: <p>I'm often writing code that compares two objects and produces a value based on whether they are the same, or different, based on how they are different.</p>
  
  <p>So I might write:</p>
  
  <pre><code>val result = (v1,v2) match {
    case (Some(value1), Some(value2)) =&gt; "a"
    case (Some(value), None)) =&gt; "b"
    case (None, Some(value)) =&gt; "b"
    case _ = &gt; "c"
  }
  </code></pre>
  
  <p>Those 2nd and 3rd cases are the same really, so I tried writing:</p>
  
  <pre><code>val result = (v1,v2) match {
    case (Some(value1), Some(value2)) =&gt; "a"
    case (Some(value), None)) || (None, Some(value)) =&gt; "b"
    case _ = &gt; "c"
  }
  </code></pre>
  
  <p>But no luck.</p>
  
  <p>I encounter this problem in a few places, and this is just a specific example, the more general pattern is I have two things, and I want to know if one and only one of them meet some predicate, so I'd like to write something like this:</p>
  
  <pre><code>val result = (v1,v2) match {
    case (Some(value1), Some(value2)) =&gt; "a"
    case OneAndOnlyOne(value, v: Option[Foo] =&gt; v.isDefined ) =&gt; "b"
    case _ = &gt; "c"
  }
  </code></pre>
  
  <p>So the idea here is that OneAndOnlyOne can be configured with a predicated (isDefined in this case) and you can use it in multiple places.</p>
  
  <p>The above doesn't work at all, since its backwards, the predicate needs to be passed into the extractor not returned.</p>
  
  <p>How about something like this?</p>
  
  <pre><code>val result = (v1,v2) match {
    case (Some(value1), Some(value2)) =&gt; "a"
    case new OneAndOnlyOne(v: Option[Foo] =&gt; v.isDefined )(value) =&gt; "b"
    case _ = &gt; "c"
  }
  </code></pre>
  
  <p>with:</p>
  
  <pre><code>class OneAndOnlyOne[T](predicate: T =&gt; Boolean) {
    def unapply( pair: Pair[T,T] ): Option[T] = {
      val (item1,item2) = pair
      val v1 = predicate(item1)
      val v2 = predicate(item2)
  
      if ( v1 != v2 )
        Some( if ( v1 ) item1 else item2 )
      else
        None
    }
  }
  </code></pre>
  
  <p>But, this doesn't compile.</p>
  
  <p>Can anyone see a way to make this solution work? Or propose another solution? I'm probably making this more complicated than it is :)</p>