我在Haskell中做的一些计算的一部分产生了一个函数列表,它将Float
映射到Float
。我想一个参数,适用于所有这些功能,比如:Haskell:映射函数应用程序
-- x :: Float
-- functions :: [Float -> Float]
map (\f -> f x) functions
有没有办法做到这一点而不使用一个扔掉的lambda函数的?我搜索Hoogle我认为签名应该是([a -> b] -> a -> [b]
)没有运气。
我在Haskell中做的一些计算的一部分产生了一个函数列表,它将Float
映射到Float
。我想一个参数,适用于所有这些功能,比如:Haskell:映射函数应用程序
-- x :: Float
-- functions :: [Float -> Float]
map (\f -> f x) functions
有没有办法做到这一点而不使用一个扔掉的lambda函数的?我搜索Hoogle我认为签名应该是([a -> b] -> a -> [b]
)没有运气。
可以使用$
运营商,这仅仅是功能应用:(这预示着x
在范围为表达)
map ($ x) functions
Hoogle唯一能找到的功能,而不是任意表达式。由于您使用的是map
,因此您希望搜索诸如(a -> b) -> a -> b
之类的函数,而不是涉及列表的任何内容。给定一个正常的函数,将它传递给map
使其对列表起作用。
是的,我觉得我对签名有些困惑。谢谢!我理解'$'如何定义优先级,但是在这种情况下它是如何工作的? –
运算符的定义非常简单:'f $ x = f x'。所以它实际上只是功能应用,作为一个操作员。当你部分应用它时,你会得到一些等同于'\ f - > f $ x'的东西;使用上面的定义,这可以解释为'\ f - > f x',这正是你所拥有的。 –
据我所知,'map f xs'对'xs'中的每个'x'都做'f x'。所以它看起来像'$ f x',因此我的困惑! –
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
的代名词。根据某种语义,<*>
适用于左侧的应用函子中的“携带”,以及右侧的内容。对于裸列表,语义与列表monad相同 - 进行所有可能的组合 - 将每个函数从左边应用到右边的每个对象,然后pure x = [x]
。对于标记的列表(即,newtype
d)为ZipList
s,语义是“拉链”应用 - 即一对一和pure x = ZipList $ repeat x
。
好吧,我有时间学习一些monads?谢谢! –
不是单子,应用函子。 :) –
这些函数实际上是为应用函子定义的,而不是单子。应用程序更普遍 - 所有monad也是应用程序,但反之亦然。 –
请参阅http://stackoverflow.com/questions/11709350 –
只是单挑,有一个名为'pointfree'('cabal install pointfree')的程序,可以自动执行这些类型的缩减。例如'map(\ f - > f x)fs'根据需要变成'map($ x)fs'。 – huon