実数式で単項演算と 2 項演算を実装する次の不自然な例を考えてみましょう。
abstract class DoubleE
case class Negate(x: DoubleE) extends DoubleE
case class Reciprocal(x: DoubleE) extends DoubleE
case class Mult(lhs: DoubleE, rhs: DoubleE) extends DoubleE
case class Div(lhs: DoubleE, rhs: DoubleE) extends DoubleE
...
// a lot more binary operations
今、私は次のようなことをしたい:
(e: DoubleE) match {
case DoubleEUnary(x) => ... // use x ...
case DoubleEBinary(a, b) => ... // use a and b ...
}
また、一致した型も参照したい場合があります。例えば
e match {
case DoubeEBinary(a, b) => DoubleEBinary(b, a)
...
}
私が試した失敗した試みのいくつか:
abstract case class DoubleEBinary(a: DoubleE, b: DoubleE)
+ それから拡張しますが、これは許可されていません: エラー: ... ケースごとの継承は禁止されています。この制限を克服するには、エクストラクタを使用して非リーフ ノードでパターン マッチを行います。上記のエラーが示唆しています:
abstract case class DoubleEBinary(a: DoubleE, b: DoubleE) def unapply(binOp: DoubleEBinary) = Some((a, b))
どちらも機能しません:エラー: 見つかりません: 値 DoubleEBinary
- ケースエイリアスを使用しようとしています
case binOp @ (Mult(a, b) | Div(a, b) | ...) => ...
case binOp(a, b) @ (Mult(_, _) | Div(_, _) | ...) => ...
case (binOp @ Mult(a, b)) | (binOp @ Div(a, b)) => ...
私が試していないことの 1 つは、ネストされた関数でオーバーロードすることです。これはやり過ぎのようです...
上記のようなシナリオで複数のケース クラスを一致させる良い方法はありますか?
注: 継承にメソッド、クラス、特性を追加しても問題ありません。