我对foldr的用法有疑问。
说我想以这种方式使用foldr:
foldr (\x y -> (x + y)/2) 2 [4,5,6]
在这种情况下y
代表列表的每个元素吗?
特别是,让我们打开这个功能。
我们有(x = 2,y = 6) - > (2 + 6)/ 2 = 4.
接下来,我们有x = 4,y = 5吗?
我问的是我真正想问的简化版。这里,x和y的内容很重要,因为在我的应用程序中,我有一个函数将第一个参数作为类型a,第二个参数作为类型b。因此,我确实需要了解最新情况。
答案 0 :(得分:2)
说我想以这种方式使用foldr:
foldr (\x y -> (x + y)/2) 2 [4,5,6]
在这种情况下
y
代表列表的每个元素吗?
解决问题的一种方法是查看foldr
的类型:
GHCi> :t foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
折叠的结构对于某些t a
类型Foldable t
(在您的情况下,您有一个列表,因此t
是[]
),其元素包含a
输入b
。通过折叠累积的结果具有类型a -> b -> b
。用于折叠的二进制函数具有类型{{1}},因此元素作为第一个参数传递,累积值作为第二个参数传递。
另一种解决方法是阅读the actual implementation of foldr
for lists(我通过查找Foldable
instance of lists找到了这个,然后点击源链接)。您可能想尝试一下,看看一张图片如何与另一张图片对应。
答案 1 :(得分:1)
foldr f startingValue (x:xs)
扩展为f x (foldr f startingValue xs)
,foldr f startingValue []
扩展为startingValue
,所以在您的情况下:
foldr (\x y -> (x + y)/2) 2 [4,5,6]
(\x y -> (x + y)/2) 4 (foldr (\x y -> (x + y)/2) 2 [5,6])
(\x y -> (x + y)/2) 4 ((\x y -> (x + y)/2) 5 (foldr (\x y -> (x + y)/2) 2 [6]))
(\x y -> (x + y)/2) 4 ((\x y -> (x + y)/2) 5 ((\x y -> (x + y)/2) 6 (foldr (\x y -> (x + y)/2) 2 [])))
(\x y -> (x + y)/2) 4 ((\x y -> (x + y)/2) 5 ((\x y -> (x + y)/2) 6 2))
(\x y -> (x + y)/2) 4 ((\x y -> (x + y)/2) 5 4)
(\x y -> (x + y)/2) 4 4.5
4.25
使用f x y = (x + y)/2
可能更容易看到:
foldr f 2 [4,5,6]
f 4 (foldr f 2 [5,6])
f 4 (f 5 (foldr f 2 [6]))
f 4 (f 5 (f 6 (foldr f 2 [])))
f 4 (f 5 (f 6 2))
f 4 (f 5 4)
f 4 4.5
4.25
如果您了解如何构建利弊列表(使用:
),您可以将foldr
视为将所有:
替换为您提供的功能。