我想我有点理解应用程序仿函数在Haskell中是如何工作的,我将它们用于基本数据类型(Maybe,Either ......)。但是,我发现了this question以下示例:
withPool pool = bracket (takeConn pool) (putConn pool)
可以用应用风格重写:
withPool = bracket <$> takeConn <*> putConn
我很惊讶它编译了,确实它按预期工作,但有人可以告诉我哪个Applicative Functor用于此以及它是如何定义的?
更新:我想我弄清楚它是如何工作的,但我不知道它在哪里定义。
答案 0 :(得分: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
。至少如果我没记错的话。