[英]How does the foldr function in haskell work in this case?
因此,我是Haskell的新手,我有点遇到了以下表达式,但我并没有对其进行foldr (.) (+3) [(*2), (+5)] 13
了解: foldr (.) (+3) [(*2), (+5)] 13
它给出了结果:42现在我知道文件foldr
通常在以下示例中起作用:文件foldr (+) 0 [1,2,3]
类似于: (1+(2+(0+3)))
但添加了另一个函数(.)
我有点困惑。 因此,如果您有任何人可以向我确切解释haskell如何解释这种表达,那就太好了,谢谢!
评论可能已经为您解决了这一问题。 但是,如果没有:
(。)是函数组成:
f . g
= \x -> f $ g $ x
= \x -> f (g x).
像(* 2)
这样的形式是糖,表示形式\\x -> x * 2
现在,观察一下
foldr op base [a,b]
是相同的
a `op` (b `op` base)
当然,这也适用于更多的参数。 例如,
foldr (+) 0 [1,2,3,4,5]
只是
1 + 2 + 3 + 4 + 5 + 0
在您的情况下,您询问
foldr (.) (+3) [(*2), (+5)]
这是(对于Integer
)
(*2) . (+5) . (+3)
= \x -> (*2) $ (+5) $ (+3) $ x
= \x -> (*2) $ (+5) $ x + 3
= \x -> (*2) $ x + 3 + 5
= \x -> (x + 3 + 5) * 2
= \x -> x*2 + 16
所以
foldr (.) (+3) [(*2), (+5)] 13
= (\x -> x*2 + 16) 13
= 13*2 + 16
= 26 + 16
= 42
foldr fz
可以看作是用f
替换列表的“ cons” (:)
,用z
替换空列表。 因此,这意味着文件foldr fz [x 1 , x 2 … x n ]
等于fx 1 (fx 2 ( … (fx n z) … ))
[(*2), (+5)]
是(:) (*2) ((:) (+5) [])
语法糖,因此我们可以用(.) (*2) ((.) (+5) (+3))
,这是(*2) . (+5) . (+3)
的详细形式(*2) . (+5) . (+3)
(*2) . (+5) . (+3)
(*2) . (+5) . (+3)
。 因此,这是一种功能。 如果使用此函数并以13
作为参数来创建函数应用程序,则会得到:
((*2) . (+5) . (+3)) 13
-> ((*2) . (+5)) 16
-> (*2) 21
-> 42
foldl fz [x 1 , x 2 … x n ]
等于f (… (f (fzx 1 ) x 2 ) … ) x n
。 因此,这里意味着foldl (.) (+3) [(*2), (+5)]
等于(.) ((.) (+3) (*2)) (+5)
,或更详细(+3) . (*2) . (+5)
(+3) . (*2) . (+5)
(+3) . (*2) . (+5)
。 如果我们对13
进行评估,则可以获得:
((+3) . (*2) . (+5)) 13
-> ((+3) . (*2)) 18
-> (+3) 36
-> 39
在Haskell(以及lambda演算)中,您可以减少Eta
在您显示的示例中,很长的写法是:
foldr (\f h -> f . h) (\x -> x+3) [(\x -> x*2), (\x->x+5)] 13
现在,您可以像下面这样逐个应用Eta减少:
(\f h -> f . h)
(\f -> (f.))
(.)
下一个:
(\x -> x+3)
(+3)
(\\ x-> x * 2),(\\ x-> x + 5)类似于(+3)
所以最后您得到了等效的表达式:
foldr (.) (+3) [(*2), (+5)]
这意味着组成每个函数,当列表为空时,应用(+3)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.