Mac*_*cki 4 haskell functional-programming composition functor applicative
给定值f
类型:: Applicative f => f (a -> b -> c)
,将参数映射到内部函数的最佳方法是什么.
到目前为止,我发现了以下内容:
(\x -> x a b) <$> f
(flip ($ a) b) <$> f
($ b) <$> ($ a) <$> f
我想我的问题是为什么Haskell没有:: a -> b -> (a -> b -> c) -> c
功能.或者是吗?
该Applicative
班有<*>
运营商(通常发音为"AP",并且是等同于Control.Monad.ap
大多数Monad
S),与该组合<$>
运算符(本身只是一个中缀别名fmap
)让你写代码像
-- f :: a -> b -> c
-- fa :: Applicative f => f a
-- fb :: Applicative f => f b
f <$> fa <*> fb :: Applicative f => f c
Run Code Online (Sandbox Code Playgroud)
如果需要应用纯参数,则使用该类的pure
方法Applicative
:
-- f :: a -> b -> c
-- a :: a
-- b :: b
f <$> pure a <*> pure b :: Applicative f => f c
Run Code Online (Sandbox Code Playgroud)
一个例子可能是
sumOfSquares :: Num a => a -> a -> a
sumOfSquares a b = a * a + b * b
> sumOfSquares <$> Just 1 <*> Just 2
Just 5
> sumOfSquares <$> Just 1 <*> Nothing
Nothing
> sumOfSquares <$> pure 1 <*> pure 2 :: Maybe Int
5
> sumOfSquares <$> readLn <*> readLn :: IO Int
1<ENTER>
2<ENTER>
5
Run Code Online (Sandbox Code Playgroud)
在Applicative f => f (a -> b -> c)
正在建造f <$>
在这里,所以如果你已经有这样的事情
> let g :: IO (Int -> Int -> Int); g = undefined
Run Code Online (Sandbox Code Playgroud)
然后你可以用它作为
> g <*> pure 1 <*> pure 2
Run Code Online (Sandbox Code Playgroud)
该<*>
运营商有型
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
因此,如果你的函数有类型x -> y -> z
,然后a ~ x
和b ~ y -> z
,如此反复AP的折叠<*>
(得到它?)传递更多参数传递给你的包裹功能.