用于在 Applicative 中应用纯值的预定义 Haskell 运算符?

Predefined Haskell operator for applying pure values in an Applicative?

如果我有一个包含在 Applicative 中的函数(例如 a -> b 类型的函数)和一个可以应用于它的值(即 a 类型的值上面的例子),我可以按如下方式应用它:

doSomething :: Applicative f => f (a -> b) -> a -> f b
doSomething wrappedFn arg = wrappedFn <*> (pure arg)

我发现自己经常这样做。是否有标准的预定义运算符可以使这段代码更简洁,或者我需要自己定义一个?如果是后者,有没有约定俗成的名字?

这个运算符实际上有一个比较知名的版本,即 (??) from lens:

(??) :: Functor f => f (a -> b) -> a -> f b

注意 Functor 约束。事实证明 Applicative 不是必需的,因为它可以定义为 \f x -> ($ x) <$> f.

(??) 的规范用例是函数函子,作为中缀 flip:

GHCi> execState ?? [] $ modify (1:)
[1]

在一般情况下,它完全符合您的要求:

GHCi> [negate] ?? 3
[-3]

(就个人而言,我仍然觉得 [negate] <*> pure 3 更具可读性,但 YMMV。)

Is there a standard, predefined operator somewhere that will make this code more concise…?

没有

… or do I need to define one myself?

是(除非你想导入外部包)。

If the latter, is there a conventional name for it?

叫做(??) in lens, and some have other names。根据镜头,它是 flip 的广义变体,这是有道理的:

flip ::             (a -> b -> c) -> b -> a -> c
(??) :: Functor f => f   (b -> c) -> b -> f c

f 替换为 ((->) a,您将从 (??) 得到 flip。因此,你可以称之为广义翻转.

顺便说一下,你不需要 ApplicativeFunctor 就够了:

gFlip :: Functor f => f (a -> b) -> a -> f b
gFlip f x = fmap ($x) f

一些示例:

ghci> gFlip [(+ 1),(* 2)] 2
[3, 4]
ghci> gFlip (++) "world" "hello"
"helloworld"