2016-05-23 3 views
0

作品次のコード(私はそれが奇妙だけど、私は、再帰関数を使用してストリームの連結をテストしたい)ストリームScalaで

def ones(s: Stream[Int]): Stream[Int] = 1 #:: ones(s) 
ones(Stream.from(1)).take(10).toList 

私はと等価である必要があり、いくつかのエリクシルのコードを書きましたスカラコードとそれがハングアップします。上記のスカラーコードと同じ効果を得るにはどうすればよいですか?

defmodule Ones do 
    def ones(s) do 
    head = Stream.take(s, 1) 
    Stream.concat(head, ones(s)) 
    end 
end 

Ones.ones(Stream.iterate(1, &(&1 + 1))) |> Enum.take(10) # hang 
+0

再帰を停止するための条件を指定していないため、ハングアップしています。 スカラについてはわかりませんが、ストリームが遅延しているので、ストリームから10個の要素しか取らないように見えます。 間違っていると私を修正してください、私はちょうど初心者です) – nightire

+0

@nightireスカラーコードはエリクシールコードとまったく同じですが、1つは仕事であり、他のものはそうではありません。なぜ2つの言語が違う振る舞いをしているのかわかりません。あなたのコメントのために – blueiur

答えて

1

scalaの#::演算子が正しい引数を遅延評価するようです。だから、あなたはそれのような "無限の"再帰を構築することができ、それはまだ動作します。エリクシルでは、遅延評価された引数の概念はないので、は常に最後にones(s)を呼び出し、無限ループになります。これを避けるには、結果を構成するために遅延値を明示的に扱うStream関数を使用する必要があります(例:Stream.resource)。

+0

Thx私はプライムストリームhttp://exercism.io/submissions/612742e25fc84703ba091138cbef18e9のためにそれが必要です – blueiur

+0

'Stream.resource'はそれに十分でなければなりません –

関連する問題