簡體   English   中英

需要幫助理解這個 Haskell 函數的作用

[英]Need help understanding what this Haskell function does

不確定這到底是做什么的,或者在函數中輸入什么以在輸出中找到模式

f0 f id [] = id

f0 f id (x:xs) = f x (f0 f id xs)

fid在每次遞歸調用中都保持不變,所以讓我們稍微簡化一下:

f0 [] = id
f0 (x:xs) = f x (f0 xs)

這意味着f0 xs可以擴展為:

f x1 (f x2 (f x3 id))

哪種看起來像foldr 那是因為它是foldr

Prelude> foldr (+) 0 [1, 2, 3]
6
Prelude> f0 (+) 0 [1, 2, 3]
6

好的。 讓我們來看看吧。 這是一個具有基本情況和遞歸步驟的遞歸函數。 它被命名為f0並具有三個參數, fid (它與 Prelude 中的函數具有相同的名稱,令人困惑)和(x:xs) 不幸的是,它沒有類型簽名,但我們已經可以看出第三個是某種列表。 所以它的簽名將類似於f0 :: a -> b -> [c] -> d

基本情況很簡單:如果第三個參數是一個空列表,則函數返回id ,因此它具有函數返回的類型。 所以這兩種類型是相同的,我們可以將類型簽名細化為f0 :: a -> b -> [c] -> b

遞歸情況僅在列表(x:xs)不為空時才被調用。 它調用f ,因此它必須是一個有兩個參數的函數,其中x (列表的頭部)作為f的第一個參數,對f0的調用作為第二個參數。 由於f的返回值是f0的有效返回值,因此它們必須具有相同的返回類型。 因此,此時我們可以推斷,如果bf0的返回類型,而[a]是第三個參數的類型,則該函數的簽名必須是:

f0 :: (a -> b -> b) -> b -> [a] -> b

現在,讓我們仔細看看遞歸步驟中f的第二個參數。 它調用f0 f id xs ,這是完全相同的調用,但是在列表的尾部。 (因此,列表每一步都縮短一個元素,直到它為空並且我們達到基本情況,因此算法必須終止。)因此, f0 (+) 0.0 [1,2,3]擴展為1 + (2 + (3 + 0.0) ) 這是 Prelude 的一個功能; 你能說出哪個嗎?

編輯:另一個答案破壞了它,但我會注意到名稱也是提示。 f0f函數id標識元素的縮寫(因為預期模型是將它添加到列表的最后一個元素並返回相同的元素,添加 3 + 0.0 的方式為您提供浮點數3.0),而x:xs是在遞歸函數中引用列表參數的傳統方式。

為了破譯代碼,我有時發現利用Data.SimpleReflect並運行一些測試很有用。

> import Debug.SimpleReflect
> let f0 f id [] = id ; f0 f id (x:xs) = f x (f0 f id xs)
> f0 f a [b,c,d,e]
f b (f c (f d (f e a)))

看起來很眼熟……是foldr嗎?

> foldr f a [b,c,d,e]
f b (f c (f d (f e a)))

好的,是的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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