我在 Haskell 中进行的一些计算的一部分会生成一个映射Float
到Float
. 我想对所有这些函数应用一个参数,如下所示:
-- x :: Float
-- functions :: [Float -> Float]
map (\f -> f x) functions
有没有办法在不使用一次性 lambda 函数的情况下做到这一点?我已经在Hoogle上搜索了我认为签名应该是 ( [a -> b] -> a -> [b]
) 的内容,但没有运气。
您可以使用$
运算符,它只是功能应用程序:
map ($ x) functions
(这假定它x
在表达式的范围内。)
Hoogle 只能查找函数,不能查找任意表达式。由于您使用的是map
,因此您想搜索类似的功能,(a -> b) -> a -> b
而不是任何涉及列表的功能。给定一个普通函数,将其传递给map
它使其作用于列表。
functions <*> pure x
应该这样做。先导入Control.Applicative
模块。
还要考虑这个:
Prelude Control.Applicative> [(1+),(2+)] <*> pure 4
[5,6]
Prelude Control.Applicative> [(1+),(2+)] <*> [4]
[5,6]
Prelude Control.Applicative> [(1+),(2+)] <*> [4,5]
[5,6,6,7]
Prelude Control.Applicative> [(+)] <*> [1,2] <*> [4,5]
[5,6,6,7]
Prelude Control.Applicative> (+) <$> [1,2] <*> [4,5]
[5,6,6,7]
Prelude Control.Applicative> getZipList $ ZipList [(1+),(2+)] <*> ZipList [4,5]
[5,7]
Prelude Control.Applicative> getZipList $ ZipList [(1+),(2+)] <*> pure 4
[5,6]
<$>
只是 的同义词fmap
。<*>
根据某种语义,将左侧应用函子中“携带”的内容应用于右侧的内容。对于裸列表,语义与 list monad 相同 - 进行所有可能的组合 - 将左侧的每个函数应用于右侧的每个对象,并且pure x = [x]
. 对于标记为 s 的列表(即newtype
d)ZipList
,语义是“zippery”应用程序 - 即一对一和pure x = ZipList $ repeat x
.