2017-04-11 22 views
1

如果我有一个功能(例如类型a -> b的)包裹在一个Applicative和可施加到其上的值(即在上述示例中a类型的值),I可以如下应用它:预定义的Haskell运算符用于在Applicative中应用纯数值?

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

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

+1

[本?](http://hayoo.fh-wedel.de/?查询=应用程序+ f +%3D%3E + f +%28a + - %3E + b%29 + - %3E + a + - %3E + f + b) – Alec

+2

请注意,'doSomething'不能节省您输入的时间。它只是通过调用'doSomething'来代替'<*>'和'pure'的调用。重要的是,它不会扩展到2+参数函数,特别是如果你想允许一些参数是纯的而且有些被包装的话。我认为仅仅编写'纯x'和'f <*> x <*>纯y''可读性更好。 – amalloy

+0

@Alec - 是的,这似乎是我正在寻找的。想知道为什么hoogle没有找到它...... – Jules

回答

6

有一个标准的,预定义的操作符,可以使代码更加简洁......?

...还是我需要定义一个自己?

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

如果是后者,是否有一个传统的名字呢?

镜头中叫做(??),有的有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" 
3

有实际上是该运营商的中等知名的版本,即(??) 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更具可读性,但情况因人而异。)

+2

就我个人而言,我发现'[negate 3]'或'[-3]'更具可读性:D。 – Zeta

+1

@泽塔我可能应该更新我的微不足道的例子:D – duplode