2012-08-14 36 views
7

This great daily Scala articleは、マッチングにおける型消去を克服する方法を説明しています。私はパラメータ化された型のIndexesSeqを変換するテクニックを適用しようとしていますが、マッチは失敗しています。これはなぜですか、どうすれば修正できますか?マニフェストと一致するスカラパターン

object Example extends App{ 
    class TableColumn[T](
     val values: IndexedSeq[T], 
     val name: Option[String] = None 
    )(implicit val m: Manifest[T]) 

    class Def[C](implicit desired : Manifest[C]) { 
     def unapply[X](c : X)(implicit m : Manifest[X]) : Option[C] = { 
      //println("m.toString+", "+desired.toString) 
      def sameArgs = desired.typeArguments.zip(m.typeArguments).forall { 
       case (desired,actual) => desired >:> actual 
      } 
      if (desired >:> m && sameArgs) Some(c.asInstanceOf[C]) 
      else None 
     } 
    } 

    val IntTableColumn = new Def[TableColumn[Int]] 
    val DoubleTableColumn = new Def[TableColumn[Double]] 

    class Analysis(data: IndexedSeq[TableColumn[_]]){ 
     val transformedData = data.map{_ match{ 
      case IntTableColumn(tc) => println("Column of Int! "+ tc) 
      case DoubleTableColumn(tc) => println("Column of Double! "+ tc) 
      case _ => println("no match") 
     }} 
    } 

    new Analysis(IndexedSeq(
      new TableColumn(IndexedSeq(1,2,3)), 
      new TableColumn(IndexedSeq(1.0,2.0,3.0)) 
    )) 
} 

私はデフに行のコメントを解除した場合、私は、このような

_分析のコンストラクタでは問題ですが、私は中に入れて他に何かわからないことを示唆している
prototype.Example$TableColumn[_ <: Any], prototype.Example$TableColumn[Int] 

としてラインを参照してくださいそこ。

+2

この記事では、「マニフェストのtypeArgumentsの使用に気づくことが重要です。これは非常にエレガント/一般的には可能です。これは、各typeArgumentのマニフェストのリストを返します。マニフェスト比較が深刻ではないため、単純に目的の== mを比較することはできません。このコードには1レベル深いジェネリックしか扱えないという弱点があります。周囲の議論はあなたにそれを修正する方法を正確に教えてくれませんが、なぜそれがうまくいかないのかを教えてください。 –

+0

@レックス:私は記事の細かい点のいくつかで迷ってしまったが、今ではそれを指摘して、問題を見て、別の方法で対処できるかどうかを考えるだろう。ありがとう – Pengin

+1

実際には2つの問題があります:1つは入れ子です。もう1つは、1つのリストに複数の型があり、型の拡大が必要です。私は最終的な解決策にいくつかの 'isAssignableFrom'を必要としていると思いますが、残念ながら私はすぐに解決策を書く時間がありません。 –

答えて

1

Rex Kerrからのコメントに感謝します。

object Example extends App{ 
    class TableColumn[T](
      val values: IndexedSeq[T], 
      val name: Option[String] = None 
    )(implicit val m: Manifest[T]) 

    class TableColumnMatcher[T](implicit desired: Manifest[T]){ 
     def unapply(tc: TableColumn[_]): Option[TableColumn[T]] = { 
      if(tc.m == desired) Some(tc.asInstanceOf[TableColumn[T]]) 
      else None 
     } 
    } 
    object TableColumnMatcher{ 
     lazy val IntTC = new TableColumnMatcher[Int] 
     lazy val DoubleTC = new TableColumnMatcher[Double] 
    } 


    class Analysis(data: IndexedSeq[TableColumn[_]]){ 
     import TableColumnMatcher._ 
     val transformedData = data.map{_ match{ 
      case IntTC(tc) => println("Column of Ints!"); 
      case DoubleTC(tc) => println("Column of Doubles!") 
      case _ => println("no match") 
     }} 
    } 

    new Analysis(IndexedSeq(
      new TableColumn(IndexedSeq(1,2,3)), 
      new TableColumn(IndexedSeq(1.0,2.0,3.0)) 
    )) 
} 
関連する問題