2012-11-21 5 views
5

は、私は次のように整数のリストを逆転しようとしていましたタイプをList[Int]として指定する必要はありませんか?左一直線の型推論?</p> <pre><code>List(1,2,3,4).foldLeft(List[Int]()){(a,b) => b::a} </code></pre> <p>私の質問は、つまり<code>_</code>が自動的にScalaのタイプ - によって満たさタイプであるいくつかの<code>List[_]</code>するシードを指定する方法があります:

おかげ

+0

実用的な理由はありますか?文脈とは何ですか? 'List [_]'は 'List [Int]'より2文字だけ短いためです。そしてリストを逆にするには、とにかく '.reverse'を使います。 – rolve

+1

スカラーの型推論システムの限界を知るには実用的な理由はなく、ちょっと変わったかゆみです。 –

+0

Ok。これに基づいて、私は理論的な答えを出しましたが、回避策はありませんでした。 – rolve

答えて

5

アップデートである方法を知っている唯一の方法: Scalaの型推論にもう少し読んだ後、私はあなたの質問に良い答えを見つけました。 Scalaの型推論の限界についてですThis articleは言う:Scalaでは

タイプ情報は、引数リスト渡って左から右に彼らの結果[...]、に関数の引数から流れ、最初からにlast acrossステートメント。これは、完全な型推論を持つ言語とは対照的です。ここでは、(大まかに言えば)型情報はすべての方向に自由に流れます。

したがって、問題は、Scalaの型推論がかなり制限されていることです。 最初のは、第1引数リスト(あなたの場合のリスト)を見て、を次に第2引数リスト(関数)にとします。しかし、それは戻っていません。

これは、なぜこの

List(1,2,3,4).foldLeft(Nil){(a,b) => b::a} 

もこの

List(1,2,3,4).foldLeft(List()){(a,b) => b::a} 

がうまくいくでもありません。どうして?まず、foldLeftの署名は次のように定義されます

foldLeft[B](z: B)(f: (B, A) => B): B 

あなたが最初の引数としてzNilを使用するのであれば、コンパイラは型パラメータBNil.typeを割り当てます。 List()を使用すると、コンパイラはBList[Nothing]を使用します。

ここでは、2番目の引数fの型が完全に定義されています。あなたのケースでは、それは

(Nil.type, Int) => Nil.type 

または

(List[Nothing], Int) => List[Nothing] 

のどちらかだとその戻り値の型がList[Int]と推定されるので、どちらの場合も、ラムダ式(a, b) => b :: aは、有効ではありません。


上記の太字部分は「引数リスト」であり、「引数」ではないことに注意してください。記事は後ほど説明します。情報は右のみ間で引数リストに左から、内左から右に引数リストを流れない

タイプ。

したがって、単一の引数リストを持つメソッドを使用すると状況がさらに悪化します。

+0

信じられないほど - それは今よりずっと意味をなさない。ありがとう –

4

私は

scala> def foldList[T](l: List[T]) = l.foldLeft(List[T]()){(a,b) => b::a} 
foldList: [T](l: List[T])List[T] 

scala> foldList(List(1,2,3,4)) 
res19: List[Int] = List(4, 3, 2, 1) 

scala> foldList(List("a","b","c")) 
res20: List[java.lang.String] = List(c, b, a) 
関連する問題

 関連する問題