私はシード値x
で始まり、各ステップで新しいシード値と出力値を生成するパターンを見つけました。私の望む最終結果は、出力値のリストです。これは次の関数で表すことができる。「出力」の値が反復されている値と同じでない場合、プレリュードの反復の代替手段は何ですか?
my_iter :: (a -> (a, b)) -> a -> [b]
my_iter f x = y : my_iter f x'
where (x',y) = f x
そして、フィボナッチ数列を生成することになる、これを使用しての不自然な例:
fibs:: [Integer]
fibs = my_iter (\(a,b) -> let c = a+b in ((b, c), c)) (0,1)
-- [1, 2, 3, 5, 8...
私の問題は、私は非常にがあることをこの気持ちを持っているということですおそらくこの種のものをするもっと慣用的な方法です。私の機能の慣用的な選択肢は何ですか?
私が今考えている唯一のものは、プレリュードのiterate
ですが、いくつかの欠点があります。
一つの方法別のf1とf2関数にfを分割する全く自然な方法が存在しない場合は、これは醜い見ることができる最初の反復と
my_iter f x = map f2 $ iterate f1 x
where f1 = fst . f
f2 = snd . f
後にマップすることです。 (実際のフィボナッチの場合、これは簡単ですが、生成された値が種の「独立」関数ではないので、事を分割するのが簡単ではない場合があります)
もう1つの方法は、一緒種と「出力」の値、および(種類のものをソートするための「シュワルツ変換」のように)それらを分離するために、別のステップを使用します。
my_iter f x = map snd . tail $ iterate (f.fst) (x, undefined)
しかし、これは奇妙なようで、私たちは忘れてはいけないので、シード(f.fst)ビットに到達するために生成された値を無視し、最初に生成されたダミー値に "未定義"値が必要です。
興味深いのは、「おそらく(a、b)」の部分は '(a、')の基礎となる '展開するための)固定小数点。 @missingnoが要求したバージョンは 'Stream a'の' unfoldr'です。その基礎となるファンクタは '(a、_)'です。 Prelude 'unfoldr'の追加の' Nothing'は、あなたのリストの生成を止めたいところをカバーしますが、ここでは決して起こらないでしょう。 – copumpkin
@copumpkin: '[a]'はよく知られている有限で有限で潜在的に無限のリストの3つすべてが永続的なペットのかわいこの1つです。 >:[ –