1

実数式で単項演算と 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 つは、ネストされた関数でオーバーロードすることです。これはやり過ぎのようです...

上記のようなシナリオで複数のケース クラスを一致させる良い方法はありますか?

: 継承にメソッド、クラス、特性を追加しても問題ありません。

4

2 に答える 2

2

エラーメッセージのヒントは、次のことです。

scala> object Binary { def unapply(e: Mult) = Mult.unapply(e) ; def unapply(e: Div) = Div.unapply(e) }
defined object Binary

scala> Div(null,null) match { case Binary(a,b) => (a,b) }
res3: (DoubleE, DoubleE) = (null,null)

申し訳ありませんが、ここで寝ようとしてunapply(b: Binary)DoubleE.unapply(d: DoubleE)ます。

于 2014-09-21T08:54:31.440 に答える