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

时间:2017-04-11 02:58:43

标签: haskell operators applicative

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

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

我发现自己做了很多。是否有一个标准的预定义运算符可以使这些代码更简洁,或者我是否需要自己定义一个?如果是后者,是否有传统名称?

2 个答案:

答案 0 :(得分:6)

  

是否有一个标准的预定义运算符可以使这段代码更简洁......?

没有

  

...或者我需要自己定义一个吗?

是(除非您要导入外部包)。

  

如果是后者,是否有传统名称?

镜头中称为(??),有些人other names。根据镜头,它是flip的广义变体,这是有道理的:

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

f替换((->) aflip获得(??)。因此,您可以将其称为广义翻转

顺便说一句,您不需要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"

答案 1 :(得分:3)

实际上有一个中等知名的运算符版本,即(??) from lens

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

请注意Functor约束。事实证明,Applicative并非必要,因为它可以定义为\f x -> ($ x) <$> f

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

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

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

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

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