[英]How to define a list of recursive calls to a function in Haskell
我想要做的是定義一個這樣的函數:
[f 0, f f 0, f f f 0, f f f f 0, f f f f f 0..]
或者換句話說,每個元素是通過函數運行的最后一個元素。
我已經嘗試過幾次使用類似於我在Haskell中看到Fibonacci序列的方法,通過使用預定義的前幾個元素調用列表:
fib = 0 : 1 : zipWith (+) fib (tail fib)
ls = 0 : f 0 : f (last ls)
如果我將f定義為一個簡單的addOne函數,如下所示:
f =(+ 1)
我收到此錯誤:
<interactive>:124:5: error:
* Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [[a]]
Actual type: [a]
* In the expression: 0 : (f 0) : f (last y)
In an equation for `y': y = 0 : (f 0) : f (last y)
* Relevant bindings include
y :: [[a]] (bound at <interactive>:124:1)
如何創建一個像這樣的功能列表?
我喜歡你的嘗試
ls = 0 : f 0 : f (last ls)
這些都是它的問題:
f
直接應用於列表,但它應該在列表元素上運行。 (這是您的錯誤消息的原因。) last
一個無限的名單可能沒有好處。 無論如何這不是你想要的: f
應該應用於尾部的所有元素。 這就是map
的用途。 因此,該嘗試的正確和完整實現如下:
iterate' :: (a -> a) -> a -> [a]
-- altn.: (Int->Int) -> [Int], without x₀ but always starting from 0
iterate' f x₀ = ls
where ls = x₀ : f x₀ : map f (tail ls)
NB這實際上並沒有給出[f 0, f (f 0), f (f (f 0)) ..]
但是從0
開始。 要從f 0
開始,只需刪除獨立的x₀
:
iterate' f x₀ = ls
where ls = f x₀ : map f (tail ls)
...然而,這並沒有終止(感謝@WillNess),因為tail
現在會永遠地遞歸。 但你實際上並不需要tail
! 這是正確的定義:
iterate' f x₀ = ls
where ls = f x₀ : map f ls
Haskell已經有了一個函數: iterate :: (a -> a) -> a -> [a]
。 例如:
Prelude> take 10 (iterate (2*) 1)
[1,2,4,8,16,32,64,128,256,512]
你的問題略有不同,因為第一個元素應該是f 0
而不是0
,但我們可以簡單地對它應用f
,或者對結果使用tail :: [a] -> [a]
。 例如:
ls :: Num a => (a -> a) -> [a]
ls = tail . flip iterate 0
例如:
Prelude> take 10 (ls (1+))
[1,2,3,4,5,6,7,8,9,10]
或滾動你自己:
fn f a = (f a) : (fn f (f a))
main = print $ take 6 $ fn (5+) 1
輸出:
[6,11,16,21,26,31]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.