4

たくさんの Java といくつかの Haskell を試した後、Scala を見てみたいと思いました。以下のコードから、このエラーメッセージが表示されます

type mismatch; found : List[Nothing] => Option[Nothing] required: List[Int] => Option[Nothing]

何が間違っているのかわかりません:

object MyFirstScalaObject {

  def main(args: Array[String]) {
      lazy val testValues:List[List[Int]] = List((1 to 10).toList, null, List());

      println(  testFunction(last, testValues));
  }

  def testFunction[I, O](f : I => O, inputs : List[I]):
      List[(I, O)] = 
    inputs.zip(inputs.map(f));

  def last[A](xs:List[A]):Option[A] = xs match {
    case x::Nil => Some(x);
    case _::xs => last(xs);
    case _ => None;
  }

}

アドバイスをありがとう。

乾杯、

4

3 に答える 3

3

型推論が scala で機能する方法のため、型パラメーターがどうあるべきかを判断することができないlastため、過度に保守的なフォールバック推測であるNothing.

を呼び出すときに、型を明示的に指定できますtestFunction

testFunction[List[Int],Option[Int](last, testValues)

または、宣言内の型パラメーター間の関係をより完全に文書化できますtestFunction。これにより、型推論器により多くの情報が提供されます。

def testFunction[A, I[_], O[_]](f : I[A] => O[A], inputs : List[I[A]]): List[(I[A], O[A])]

これは、I と O が型コンストラクター (kind * -> *) であることを明示的に示しています。f の入力/出力型がより具体的になったため、推論器は、最後の関数の A パラメーターが Int でなければならないと正しく推論できます。

于 2012-12-14T20:05:56.327 に答える
1

なぜscalaの型推論がこのように機能するのかはわかりません。

しかし、そのような場合にコンパイラを支援する一般的な方法parameter sectionsがあります- 。

def testFunction[I, O](inputs : List[I])(f: I => O): List[(I, O)] = inputs.zip(inputs.map(f))

使用法:

testFunction(testValues)(last)

同様の解決策は、testFunctionクラスにメソッドを追加することListです。

class LastsHelper[T](inputs: List[T]) {
  def testFunction[O](f: T => O): List[(T, O)] = inputs.zip(inputs.map(f))
}
implicit def toLastsHelper[T](inputs: List[T]) = new LastsHelper(inputs)

次のようなメソッドを使用できますList

testValues.testFunction(last)
于 2012-12-15T05:25:26.883 に答える
1

セニアのアイデアを使用して、完全に改訂およびテストされたバージョン:

object MyFirstScalaObject {
  def main(args: Array[String]) {
      lazy val testValues = List((1 to 10).toList, null, List())
      println(testFunction(testValues)(last))
  }

  def testFunction[I, O](inputs: List[I])(f: I => O): List[(I, O)] =
    inputs.zip(inputs.map(f))

  def last[A](xs: List[A]): Option[A] = xs match {
    case x :: Nil => Some(x)
    case _ :: xs => last(xs)
    case _ => None
  }
}

型の推論は左から右に進みます。1 つのパラメーター リストからの情報は、次のパラメーター リスト内で使用されます。このコードでは、testFunctionScalaを呼び出すとI、最初のパラメーターから推測できます。次にI、関数の入力型として入力fしてその型を把握し (つまり、引数lastが で適用されるA = Int)、最終的に の値を取得します。O関数の戻り値の型から。

于 2012-12-15T00:18:52.607 に答える