0

以下に私が持っています:

trait Elem {
  def compare: Int
}

case class DiffElem(weight: Int, len: Int) extends Elem {
  def compare = weight - len;
}

これで、関数に基づいて、Elemの多くのサブクラスが存在する可能性がありcompareます。これで、ファイルから入力を読み取り、次のリストを生成する関数ができましたDiffElem

def getInput[T <: Elem](): List[T] = {
  var ans: List[T] = List.empty[T]
  for (line <- Source.fromFile("src/week1/jobs.txt").getLines()) {
    val diff = line.split(" ")
    ans = ans match{
      case i:List[DiffElem] =>  new DiffElem(Integer.parseInt(diff(0)), Integer.parseInt(diff(1))) :: ans;
      case _ => ???
    }

  }
  ans
}

しかし、コンパイラーは、明らかに::次のような不変型の操作を許可していません。私は不変を実行しようとしています。関数シグネチャをに変換すると機能しますT >: Elemが、目的は解決されません。

より良いアプローチはありますか?

4

2 に答える 2

3

getInput 内で DiffElem を構築している場合、任意の T <: Elem のリストを取得する方法 (および理由) は? このようなことを行うには、DiffElem から別の T <: Elem に変換できる必要があり、その変換可能性は次のように暗黙的にキャプチャできます。

  def getInput[T <: Elem](implicit conv: DiffElem => T): List[T] = ...

、しかし、あなたは本当にそれが欲しいですか?DiffElem のリストだけで満足する場合は、次のように関数を関数型に書き直すことができます。

  def getInput(): List[DiffElem] =
    Source.fromFile("src/week1/jobs.txt").getLines().map { line =>
      val diff = line.split(" ")
      DiffElem(
        Integer.parseInt(diff(0)),
        Integer.parseInt(diff(1))
      )
    } toList

mapは、シーケンスの各要素の変換を、この要素にその funarg を適用した結果に取り込む高階関数です。

更新: モジュラー型駆動型リストの作成を行うには、暗黙を提案します。

  def getInput[E <: Elem](implicit mkE: (Int, Int) => E): List[E] = {
    Source.fromFile("src/week1/jobs.txt").getLines().map { line =>
      val diff = line.split(" ")      
      mkE(diff(0).toInt, diff(1).toInt)      
    } toList
  }

ここで、取得したい E <: Elem, リストに対して、次のように (Int, Int) => E 型の暗黙の値をスコープに指定する必要があります。

  implicit val diffElemBuilder = {
    (a, b) => DiffElem(a, b)
  }

そして、この暗黙が見える任意のスコープで、次のように getInput を使用できます。

val xs = getInput[DiffElem]
于 2012-12-16T13:37:22.463 に答える
-1

コードを再構築して、パターン マッチングの代わりに高ランクのポリモーフィック関数を使用することもできます。

于 2012-12-16T13:44:58.347 に答える