我理解簡單的語句調用foldr像理解不同foldr相似statments
foldr (+) 0 [1,2,3]
不過,我有更復雜的foldr相似的語句,即那些需要2個參數的功能,並與/和麻煩 - 計算。任何人都可以解釋得到這些答案的步驟嗎?
foldr (\x y -> (x+y)*2) 2 [1,3] = 22
foldr (/) 2 [8,12,24,4] = 8.0
謝謝。
我理解簡單的語句調用foldr像理解不同foldr相似statments
foldr (+) 0 [1,2,3]
不過,我有更復雜的foldr相似的語句,即那些需要2個參數的功能,並與/和麻煩 - 計算。任何人都可以解釋得到這些答案的步驟嗎?
foldr (\x y -> (x+y)*2) 2 [1,3] = 22
foldr (/) 2 [8,12,24,4] = 8.0
謝謝。
的foldr
函數的定義如下:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ a [] = a
foldr f a (x:xs) = f x (foldr f a xs)
現在考慮下面的表達式:
foldr (\x y -> (x + y) * 2) 2 [1,3]
我們會給拉姆達名稱:
f x y = (x + y) * 2
因此:
foldr f 2 [1,3]
-- is
f 1 (foldr f 2 [3])
-- is
f 1 (f 3 (foldr f 2 []))
-- is
f 1 (f 3 2)
-- is
f 1 10
-- is
22
同理:
foldr (/) 2 [8,12,24,4]
-- is
8/(foldr (/) 2 [12,24,4])
-- is
8/(12/(foldr (/) 2 [24,4]))
-- is
8/(12/(24/(foldr (/) 2 [4])))
-- is
8/(12/(24/(4/(foldr (/) 2 []))))
-- is
8/(12/(24/(4/2)))
-- is
8/(12/(24/2.0))
-- is
8/(12/12.0)
-- is
8/1.0
-- is
8.0
希望這有助於。
摺疊的功能參數總是有兩個參數。 (+)
和(/)
是二元函數就像一個在你的第二個例子。
Prelude> :t (+)
(+) :: Num a => a -> a -> a
如果我們改寫倍使用完全相同的第二個例子是
foldr f 2 [1,3]
where
f x y = (x+y)*2
我們可以擴展右側的相同的方案,我們會用(+)
:
foldr f 2 [1,3]
foldr f 2 (1 : 3 : [])
1 `f` foldr f 2 (3 : [])
1 `f` (3 `f` foldr f 2 [])
1 `f` (3 `f` 2)
1 `f` 10
22
值得注意的是foldr
是右結合的,這表明在如何括號窩。相反,foldl
,其有用的表弟foldl'
,是左結合。
你能想到的foldr
,maybe
和either
作爲與您所選擇的功能和/或值替換它們各自類型的數據構造函數:
data Maybe a = Nothing | Just a
maybe :: b -> (a -> b) -> Maybe a -> b
maybe nothing _just Nothing = nothing
maybe _nothing just (Just a) = just a
data Either a b = Left a | Right b
either :: (a -> c) -> (b -> c) -> Either a b -> c
either left _right (Left a) = left a
either _left right (Right b) = right b
data List a = Cons a (List a) | Empty
foldr :: (a -> b -> b) -> b -> List a -> b
foldr cons empty = loop
where loop (Cons a as) = cons a (loop as)
loop Empty = empty
所以一般情況下,你不真的要考慮一下所涉及的遞歸,只是把它作爲替代數據構造:
foldr f nil (1 : (2 : (3 : []))) == (1 `f` (2 `f` (3 `f` nil)))