用于在 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
。因此,你可以称之为广义翻转.
顺便说一下,你不需要 Applicative
。 Functor
就够了:
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"
如果我有一个包含在 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
。因此,你可以称之为广义翻转.
顺便说一下,你不需要 Applicative
。 Functor
就够了:
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"