关于haskell高阶函数
我被要求编写一个函数“pipeline”,其类型为关于haskell高阶函数,haskell,Haskell,我被要求编写一个函数“pipeline”,其类型为[a->a]->[a]->[a],在这样一个管道中,原始函数列表中的每个函数依次应用于输入的每个元素。例如,管道[(+1),(*2),pred][1,2,3]将返回[1,3,5] 解决方案表中的答案是pipeline=map。foldr(.)id,我不太明白。这个解决方案是如何产生的?思考foldr的一个方法是 foldr f z xs 将xs中的每个(:)替换为f,将空列表替换为z 注意 [(+1), (*2)] 是的缩写 (+1) : (
[a->a]->[a]->[a]
,在这样一个管道中,原始函数列表中的每个函数依次应用于输入的每个元素。例如,管道[(+1),(*2),pred]
[1,2,3]
将返回[1,3,5]
解决方案表中的答案是
pipeline=map。foldr(.)id
,我不太明白。这个解决方案是如何产生的?思考foldr
的一个方法是
foldr f z xs
将xs
中的每个(:)替换为f
,将空列表替换为z
注意
[(+1), (*2)]
是的缩写
(+1) : (*2) : []
你现在应该可以看到什么了
foldr (.) id ((+1) : (*2) : [])
评估为。从这里,你将能够理解整个表达式。折叠在某种程度上是相当混乱的,尽管它们实际上非常简单。尤其是右折叠:它基本上不做其他任何事情,只是用一些可选的给定函数替换列表中的每个
:
,并用init值替换列表的nil
。例如:
foldr (.) id [(+1),(*2),pred]
≡ foldr (.) id ( (+1) : (*2) : pred : [] )
≡ (+1) . (*2) . pred . id
因此,这只是将列表中的所有函数链接到一个大组合中
一旦你有了这个链,将它应用到另一个列表中的所有值是很简单的,
map
问题的关键在于有一个类型的函数:[a->a]->(a->a)
,即将一个函数列表转换为一个函数
foldr
的类型为:(b->c->c)->c->[b]->c
让我们看看类型如何匹配:
(b->c->c)->c->[b]->c
- 将
替换为b
:(a->a)
((a->a)->c->c)->c->[a->a]->c
- 将
替换为c
:(a->a)
((a->a)->(a->a)->(a->a)->(a->a)->[a->a]->(a->a)
- 函数的类型是
,这是我们在前一个签名的第一个类型中所拥有的(我们的都是(b->c)->(a->b)->a->c
),因此我们可以在那里使用a
()
- 对于第二部分,即
我们可以使用(a->a)
函数id
- 让我们适应这些:
,剩下的是(.)id
部分,这是我们需要的[a->a]->(a->a)
- 所以,
给了我们foldr(.)id
[a->a]->(a->a)
map
部分只是将foldr
的结果函数应用于列表的每个元素
注意:使用白板来理解所有这些,直到你的潜意识习惯了;) 我建议您查阅
map
()foldr
和id
的定义,并手动评估一个小示例。这将启发你!查看foldr(.)id[(+1),(*2)]
的计算结果就足够了。查看以下相关问题的答案: