在Haskell中应用多个参数的更简单方法

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功能.或者是吗?

bhe*_*ilr 6

Applicative班有<*>运营商(通常发音为"AP",并且是等同于Control.Monad.ap大多数MonadS),与该组合<$>运算符(本身只是一个中缀别名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 ~ xb ~ y -> z,如此反复AP的折叠<*>(得到它?)传递更多参数传递给你的包裹功能.