15

我想我有点理解应用函子在 Haskell 中是如何工作的,并且我将它们用于基本数据类型(也许,或者......)。但是,我通过以下示例发现了这个问题:

withPool pool = bracket (takeConn pool) (putConn pool)

可以用应用风格重写:

withPool = bracket <$> takeConn <*> putConn

我很惊讶它编译并且确实按预期工作,但是有人可以告诉我哪个 Applicative Functor 用于此以及它是如何定义的?

更新:我想我知道它是如何工作的,但我不知道它在哪里定义。

4

1 回答 1

17

在类型签名中统一f= :(a ->)

fmap :: (b -> c) -> (a -> b) -> (a -> c)
pure :: b -> (a -> b)
(<*>) :: (a -> b -> c) -> (a -> b) -> (a -> c)

((->) a)声明在语法上与vs不同的唯一原因(a ->)是您不允许在类型级别使用节。因此,在追逐类型之后,您最终得到了这些:

instance Functor ((->) a) where
    fmap = (.)

instance Applicative ((->) a) where
    pure = const
    f <*> g = \x -> f x $ g x

我很确定Functor实例在 中Data.Functor,并且Applicative实例在Control.Applicative. 的Monad实例((->) a)是唯一在一个奇怪的地方,在Control.Monad.Instances,而不是Control.Monad。至少如果我没记错的话。

于 2012-01-06T19:26:03.797 回答