簡體   English   中英

如何在Haskell中定義函數的遞歸調用列表

[英]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

如果你想自己定義,使用@WillemVanOnsem指出的迭代,那么簡單的原始遞歸就是你的朋友:

f :: (a -> a) -> a -> [a]
f g x = let new = g x in new `seq` new : f g new

這與iterate類似,只是iterate以您提供的元素(第一個x )而不是函數的第一個應用程序開頭:

iterate :: (a -> a) -> a -> [a]
iterate f x =  x : iterate f (f x)

可以通過對這種類型的函數進行hoogling並讀取基本包中找到的任何搜索命中的實現來獲得自我教育

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM