4

ある要素タイプのシーケンスを受け取り、別の要素タイプのシーケンスを返すメソッドを実装したいと考えています。Sequence の同じサブクラスが返されるように、これを一般的に行うにはどうすればよいですか?

私の方法は現在次のようになっています:

def lookerUpper(ids : Seq[String], someOtherInfo : Int) : Seq[UsefulData] = {
    ... retrieve data for each id ...
}

より一般的なものにして、(文字列の) どんな種類のシーケンスが渡されても、(UsefulData の) シーケンスの種類が返されるようにしたいと思います。ベクトルとリスト、特に、またはできる限り一般的です。

これは Scala の型システムで表現できますか? 「型パラメーターが異なることを除いて、この引数と同じ型を返します。」

4

1 に答える 1

3

完全な回答については、ビルダーに関するかなり長い質問と回答を参照してください (注: 2012 年 9 月の時点で、Miles の代替バージョンは 2.9 または最新の 2.10 では動作しません)。

これは、開始するためのフレームワークです (SO に表示するために過度に長い行を避けるために、明示的および暗黙的なパラメーター ブロックの奇妙な書式設定に注意してください)。

import collection.generic.CanBuildFrom

case class UsefulData(data: Int) {}

def lookerUpper[C[String]](
  ids: C[String], someOtherInfo: Int
)(
  implicit cbf: CanBuildFrom[C[String],UsefulData,C[UsefulData]],
  ev: C[String] => Iterable[String]
): C[UsefulData] = {
  val b = cbf()
  val i = ev(ids)
  i.foreach{ s => b += UsefulData(s.length + someOtherInfo) }
  b.result 
}

そして、それが機能することを観察してください:

scala> lookerUpper(Vector("salmon","cod"),2)
res0: scala.collection.immutable.Vector[UsefulData] = 
  Vector(UsefulData(8), UsefulData(5))

scala> lookerUpper(Array("salmon","cod"),2)
res1: Array[UsefulData] = 
  Array(UsefulData(8), UsefulData(5))

TraversableLike編集:(そうではない)のサブクラスのみを気Arrayにし、標準のコレクション操作を使用してすべての作業を行う場合は、Luigiが指摘するように8609398への回答を使用できます。(おそらく、この回答を別の視点としてそこに移動する必要があります。)

于 2012-09-19T18:53:06.737 に答える