假设我有一个功能列表
functions = [f, g, h]
每个类型a -> a
我还有一个值列表,比如数字但是任何东西都可以在这里工作
vals = [1,2,3]
我想将functions
中的每个功能应用到vals
我的第一直觉是使用lambda和zipWith,如:
zipWith (\f v -> f v) functions vals
但坦率地说,这看起来很难看,而不是像Haskell这样的好语言。功能应用程序功能听起来像解决方案。有这样的事吗?我错过了什么,我的问题有一个更好的解决方案吗?我实际上最终为Project Euler解决方案编写了这个构造。它有效,但我不喜欢它。
答案 0 :(得分:16)
zipWith ($) f v
$
是功能应用程序。事实上,它具有特别低的优先级,有时会引发人们的循环。
答案 1 :(得分:11)
奇怪的是,
zipWith id functions vals
也会奏效!
但是,实际上,zipWith ($)
是写这个的正确方法。
答案 2 :(得分:3)
这是另一个可能会让你思考的选项。
>>> import Control.Applicative
>>> let functions = ZipList [(+1), (*2), (*10)]
>>> let values = ZipList [1, 2, 3]
>>> getZipList (functions <*> values)
[2, 4, 30]
ZipList
只是列表的包装。 <*>
的{{1}}的定义说“通过将每个函数依次应用于参数”来压缩函数列表(在左侧)和参数列表(在右侧)。
这与常规列表的ZipList
定义形成对比,后者表示“从这两个列表中取出每个可能的(函数,参数)对,并将该函数应用于参数”。