2012-09-27 10 views
6

なぜそれがScalaのマップは

List(1,2,3,4).map((x: Int) => println(x)) 
List(1,2,3,4).foreach((x: Int) => println(x)) 
List(1,2,3,4).iterator.foreach((x: Int) => println(x)) 

はすべてやるながら

scala> List(1,2,3,4).iterator.map((x: Int) => println(x)) 

1 
2 
3 
4 

をプリントアウトしていない、ということである副作用を生成しないのですか?

つまり、タイプTをユニットにマップし、副作用がそれらの副作用を表示できないイテレータ上のマップは何故ですか?

編集:また

なぜlazyMapの次の呼び出しは、実際にイテレータが面倒であれば最初から最後まで、新たなイテレータ(完全な新しいイテレータを提供)を計算していますか?イテレータの

def lazyMap[T, U](coll: Iterable[T], f: T => U) = new Iterable[U] { 
    def iterator = coll.iterator map f 
} 

scala> lazyMap(List(1,2,3,4), (x: Int) => x + 1) 
res4: java.lang.Object with Iterable[Int] = (2, 3, 4, 5) 
+0

ところで、あなたはIterableの間違った拡張をしています(Iterableを拡張するすべてのクラスは 'newBuilder'メソッドを提供する必要があります) –

答えて

7

原因マップは怠惰であり、あなたは、いくつかの厳密が必要:あなたはイテレータ上でのforeachを行う場合

scala> List(1,2,3,4).iterator.map((x: Int) => println(x)) 
res0: Iterator[Unit] = non-empty iterator 

// nothing actually happened yet, just remember to do this printing things 

scala> res0.toList 
1 
2 
3 
4 
res1: List[Unit] = List((),(),(),()) 

あなたが副作用をやっていることは極めて明白であるので、lazynessは望ましくないだろう。私はマップについてそう言っていないだろう。

UPDあなたの編集については

:そのような行動の理由、順番にイテ​​レータをstrictsステートメントの結果のためのtoStringの暗黙の呼び出しがありますされていること - 自分でこのコードを試してみてください。

scala> { lazyMap(List(1,2,3,4), {(x: Int) => println(x); x + 1}); 1 } 

、あなたはその機能fが表示されますがイテレータのポイントは怠惰である

6

と呼ばれることはありません。つまり、Iteratorを作成すると、データを読み取るまでは何も評価されません。

scala> val itr = List(1,2,3).iterator 
itr: Iterator[Int] = non-empty iterator 

[OK]を、私たちは今、イテレータを持っている:ここではそれは次のようになります。しかし、それはまだ実際にリストを見ていない。

scala> val mappedItr = itr.map((x: Int) => println(x)) 
mappedItr: Iterator[Unit] = non-empty iterator 

ここで新しいイテレータがあります。これは、データにアクセスしたときにマップされた機能を適用します。しかし、我々まだは、実際に元のリストを見ていない。

scala> mappedItr.next 
1 

私たちがデータにアクセスしたのはこれが初めてであるため、イテレータがリストを最初に調べたのです。私たちはnextを呼び出したので、最初の要素を得ました。反復子はmapがキューに入れられているので、その要素にアクセスするときにマップされた関数を適用します。そこで、nextアイテムに適用された関数の結果を確認します。

私たちは、次の要素を取得するために、再びそれを行うことができます

scala> mappedItr.next 
2 

をそして、再び、それは私たちの最終的な結果を与えるために、する必要があるときにのみ機能を評価します。

+0

editを参照してください – platypus

関連する問題