7

私は現在、「Programming in Scala」という本を読んで Scala を学んでいます。これまでのところ、(Java プログラマーの観点から) 奇妙に見えるすべてについて適切な説明がありましたが、Stream を使用してフィボナッチ数列を生成する次の 1 つの例は、私を困惑させます。

def fibFrom(a: Int, b: Int): Stream[Int] =
  a #:: fibFrom(b, a + b)

ストリームの構築はどのように行われますか? もちろん、#::オペレーターには何らかの責任があります。で終わるので、:右結合であることは理解していますが、それではストリームの作成が説明されません。どういうわけか暗黙的にコンストラクターに変換されていると思いますが、その理由と正確な方法はわかりません。

私はすでに and で答えを探しましたが、Predef.scalaこれLowPriorityImplicits.scalaまでのところ運がありません。

誰でも私を啓発できますか?

4

2 に答える 2

8

これは正しい結合法則であるため、正しい引数のメソッドとして機能します。

fibFrom(b, a + b).#::(a)

少なくとも、それが構文的に実行しようとしていることです。Stream[Int]そのような方法はありません。幸いなことに、このメソッド(コードobject Stream)を持つクラスには暗黙的です。ConsWrapper

したがって、暗黙的な解決後に得られるのは次のとおりです。

immutable.this.Stream.consWrapper(fibFrom(b, a + b)).#::(a)
于 2012-05-04T10:49:47.683 に答える
2

ストリームはリストに似ています。これは、ストリームの先頭と残りのストリーム (Stream(head: T, tail: Stream[T])) のみを認識します。違いは、 Stream が遅延評価されることです。メソッド名の末尾の「:」は、そのメソッドが右結合であることを示しています。したがって、式 a #:: fibFrom(b, a + b) は (コンパイラによって) fibFrom(b, a + b).#::(a) に変換されます。

于 2012-05-04T10:54:30.220 に答える