私はよく、2 つのオブジェクトを比較し、それらが同じか異なるかに基づいて値を生成するコードを書いています。
だから私は書くかもしれません:
val result = (v1,v2) match {
case (Some(value1), Some(value2)) => "a"
case (Some(value), None)) => "b"
case (None, Some(value)) => "b"
case _ = > "c"
}
2番目と3番目のケースは本当に同じなので、書いてみました:
val result = (v1,v2) match {
case (Some(value1), Some(value2)) => "a"
case (Some(value), None)) || (None, Some(value)) => "b"
case _ = > "c"
}
しかし、運がありません。
いくつかの場所でこの問題に遭遇しましたが、これは単なる具体的な例です。より一般的なパターンは、2 つのものがあり、そのうちの 1 つだけが述語を満たしているかどうかを知りたいので、次のように書きたいと思います。このようなもの:
val result = (v1,v2) match {
case (Some(value1), Some(value2)) => "a"
case OneAndOnlyOne(value, v: Option[Foo] => v.isDefined ) => "b"
case _ = > "c"
}
したがって、ここでの考え方は、OneAndOnlyOne を述語 (この場合は isDefined) で構成でき、複数の場所で使用できるということです。
上記はまったく機能しません。逆方向であるため、述語は返されずにエクストラクターに渡される必要があります。
このようなものはどうですか?
val result = (v1,v2) match {
case (Some(value1), Some(value2)) => "a"
case new OneAndOnlyOne(v: Option[Foo] => v.isDefined )(value) => "b"
case _ = > "c"
}
と:
class OneAndOnlyOne[T](predicate: T => 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
}
}
しかし、これはコンパイルされません。
誰でもこのソリューションを機能させる方法を見ることができますか? または、別の解決策を提案しますか? 私はおそらくこれを実際よりも複雑にしています:)