2012-03-31 11 views
1

私は一番長い行の長さを行の集合で見つけようとしています。reduceLeftが型の不一致について不平を言っているのはなぜですか?

val lines = Source.fromFile(args(0)).getLines() //a collection of strings 
    val longestLine = lines.reduceLeft((a,b) => 
     if(a.length > b.length) a.length else b.length) 

しかし、これは次のエラー発生します

/home/jesvin/dev/scala/readfile.scala:11: error: type mismatch; 
found : Int 
required: String 
     if(a.length > b.length) a.length else b.length) 
           ^
/home/jesvin/dev/scala/readfile.scala:11: error: type mismatch; 
found : Int 
required: String 
     if(a.length > b.length) a.length else b.length) 
              ^
two errors found 

を私は特定の場所でいくつかの明示的なreturn文と型キャストを試してみましたが、それはうまくいきませんでした。

私はreduceLeftを使用していますか?

答えて

10

Am I using reduceLeft wrong?

はい、あなたはreducefoldとないの振る舞いを持っていたいです。 reduceは、コレクションの型パラメータと同じ型を生成します。別の型を生成できるのはfoldです。ここ

scala> Seq("a","b","cd").reduceLeft(_+_) 
res24: String = abcd 

、配列の型パラメータが文字列である - したがってreduceLeftは、文字列を生成します。対照的foldLeft

scala> Seq("a","b","cd").foldLeft(0)(_+_.length) 
res25: Int = 4 

別の型を生成することができ - この例のIntに。

あなたの例では、seq.maxが必要です。あなた自身でそれを実装しようとすると、実装が正しいかどうかを確認するためにソースを調べます。

ヒント:

def reduce(f: (A, A) => A) = 
    tail.fold(head)(f) 

これは、それが空のコレクションに呼び出されたときにreduceが例外をスローした理由です:reduceはこのような何かを実装しているfoldです。

2

はい、そうです。 reduceLeftは、コレクション内のオブジェクトと互換性のある型のオブジェクト(この場合はString)を返す必要があります。 Programming in Scalaを参照してください。正確にはあなたの問題 - 同じ変数名まで。

あなたが欲しい:コレクションが空であればもちろん

val longestLine 
    = lines.reduceLeft((a,b) => if(a.length > b.length) a else b).length 

を、これはのみ動作します。このような理由から、@Antorasで示されるように、foldLeftが望ましいことがよくあります。

+0

私は第3章の最後に私の学習のギャップを見つけるためにオリジナルを見ずにプログラムを書いていました。このケースでは、縮小と折り畳みの操作について十分に知りませんでした。 – aitchnyu

関連する問題