Haskell 哈斯克尔的福尔德:困惑
我只是想问一下foldr的用法 假设我想以这种方式使用foldr:Haskell 哈斯克尔的福尔德:困惑,haskell,Haskell,我只是想问一下foldr的用法 假设我想以这种方式使用foldr: foldr (\x y -> (x + y)/2) 2 [4,5,6] 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的内容非常重要,因为在我的应用程序中,我有一个函数,第一个参数是类型
foldr (\x y -> (x + y)/2) 2 [4,5,6]
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。因此,我确实需要知道引擎盖下发生了什么
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
使用fxy=(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
如果您了解cons列表是如何构造的(使用:
),您可以将foldr
看作是用您提供的函数替换所有:
。foldr f startingValue(x:xs)
扩展为fx(foldr f startingValue xs)
,以及foldr f 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
使用fxy=(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
如果您了解cons列表是如何构造的(使用:
),您可以将foldr
视为用您提供的函数替换所有:
假设我想以这种方式使用foldr:
foldr (\x y -> (x + y)/2) 2 [4,5,6]
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
正在折叠的结构具有类型ta
,对于某些可折叠的t
(在您的例子中,您有一个列表,因此t
是[]
),其元素具有类型a
。通过折叠累积的结果具有类型b
。用于折叠的二进制函数具有类型a->b->b
,因此元素作为第一个参数传递,累积值作为第二个参数传递
另一种方法是通过阅读(我通过查找源链接找到)。你可能想试试,看看一张图片和另一张图片是如何对应的
假设我想以这种方式使用foldr:
foldr (\x y -> (x + y)/2) 2 [4,5,6]
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
正在折叠的结构具有类型ta
,对于某些可折叠的t
(在您的例子中,您有一个列表,因此t
是[]
),其元素具有类型a
。通过折叠累积的结果具有类型b
。用于折叠的二进制函数具有类型a->b->b
,因此元素作为第一个参数传递,累积值作为第二个参数传递
另一种方法是通过阅读(我通过查找源链接找到)。你可能想试试,看看一张图片和另一张图片是如何对应的