私は、有限の順列セットを超える代数グループのユースケースを持っています。そうでなければ無関係な様々な置換クラスにグループを使用したいので、私はこれをミックスインの特性としてしたいと思います。ここにある時点で私の試みScalaコンパイラは、パターンマッチングのためにミックスインタイプを推論できません
trait Permutation[P <: Permutation[P]] { this: P =>
def +(that: P): P
//final override def equals(that: Any) = ...
//final override lazy val hashCode = ...
// Lots of other stuff
}
object Permutation {
trait Sum[P <: Permutation[P]] extends Permutation[P] { this: P =>
val perm1, perm2: P
// Lots of other stuff
}
private object Sum {
def unapply[P <: Permutation[P]](s: Sum[P]): Some[(P, P)] = Some(s.perm1, s.perm2)
//def unapply(s: Sum[_ <: Permutation[_]]): Some[(Permutation[_], Permutation[_])] = Some(s.perm1, s.perm2)
}
private def simplify[P <: Permutation[P]](p: P): P = {
p match {
case Sum(a, Sum(b, c)) => simplify(simplify(a + b) + c)
// Lots of other rules
case _ => p
}
}
}
の抜粋ですが、私は、よく、代数の公理を使用してグループ操作の表現を簡単にするために簡素化メソッドを呼び出すしたいと思います。パターンマッチングの使用は、評価されるべき公理がたくさんあり、構文が簡潔であるため意味があるようです。私は、コードをコンパイルする場合は、私が取得:コンパイラが正しく型を推論することはできませんし、私はそれを助ける方法がわからない、なぜ私は理解していない
error: inferred type arguments [P] do not conform to method unapply's type parameter bounds [P <: Permutation[P]]
。実際、Pのパラメータタイプは、この場合のパターンマッチングの際には無関係です。 pが任意の置換の和である場合、パターンは一致するはずです。返り値の型はPで+演算子を呼び出すだけで変換が行われるので、まだPです。
2回目の試行では、コメントアウトされたunapplyのバージョンと入れ替えます。しかし、その後、私は、コンパイラ(2.8.2)からのアサーションエラーを取得:
assertion failed: Sum((a @ _), (b @ _)) ==> Permutation.Sum.unapply(<unapply-selector>) <unapply> ((a @ _), (b @ _)), pt = Permutation[?>: Nothing <: Any]
任意の手掛かり私は、コンパイラはこれを受け入れることができますか?
ありがとうございます!
私はここに示すコードは順列形質を適用しなければならない元のクラスの一つのリファクタリング起因抜粋であることを追加する必要があります。元のコードは、表現の簡略化を含め、完全に機能しています。簡略化をノーオペレーションにすると、リファクタリングされたコードも機能します。 –
これらの行に沿ってさらにリファクタリングすることができます:http://www.artima.com/pins1ed/case-classes-and-pattern-matching.html? – huynhjl
これは、私が最初のバージョンから来ているところです。しかし、私は、このクラスをケースクラスではなく、ミックスインの特性にする必要があります。遠隔接続されているいくつかのクラスに適用したいからです。これはエクストラクタでは可能ですが、これをコンパイルすることはできません。 –