在Haskell中,是否存在(liftM.liftM),(liftM.liftM.liftM)等的别名?

Lay*_*lez 6 monads haskell lifting

在Haskell中,是否存在(liftM.liftM),(liftM.liftM.liftM)等的别名?

所以我不必如此冗长,例如:

(liftM . liftM) (+ 1) [Just 1,  Just 2]  = [Just 2, Just 3]
(liftM2 . liftM2) (+) [Just 1] [Just 2]  = [Just 3]
Run Code Online (Sandbox Code Playgroud)

And*_*ewC 7

在基础上没有这样的东西,但是在Stack Overflow上为我提出最有趣的问题已经做了一段时间.

Functors和Applicative functor在组合下是封闭的(对于monad来说肯定不是这种情况,因此需要monad变换器),这就是为什么liftA2.liftA2在这里工作,并且liftM2通常只是liftA2,特别是现在Applicative正在成为Monad的超类.

题外话:

你可以使用Data.Functor.Compose包中的组合newtype来组成一个Applicative,但是你也可以用其他方式从旧的应用程序中创建新的应用程序 - 我强烈推荐Gershom Bazerman在Comonad Reader中的民间文章"Abstracting with Applicatives"想要了解组合的Applicative结构与monad变换器堆栈相比有多漂亮 - 我现在总是在寻找使用的东西,而不是monadic,我可以获得我需要的功能.通常我可以使用Applicative将所有输入内容组合成我想要输出的值,然后将其直接传送到我正在使用的位置>>=.

您的功能和操作员

当然,没有什么可以阻止你定义自己的功能:

liftliftA2 :: (Applicative f, Applicative g) =>
              (a -> b -> c) -> f (g a) -> f (g b) -> f (g c)
liftliftA2 = liftA2.liftA2
Run Code Online (Sandbox Code Playgroud)

但它并不比它短得多liftA2.liftA2.

我喜欢你的想法是制作嵌套的Applicative运算符,但是会转而增加尖括号,而不是重复内部运算符,因为在Control.Applicative中<**>发生了冲突,而且它更符合逻辑.(<**>) = flip (<*>)

import Control.Applicative

(<<$>>) :: (Functor f, Functor g) => 
           (a -> b) -> f (g a) -> f (g b)
(<<$>>) = fmap.fmap

(<<*>>) :: (Functor m, Applicative m, Applicative n) =>
            m (n (a -> b)) -> m (n a) -> m (n b)
mnf <<*>> mna = (<*>) <$> mnf <*> mna
Run Code Online (Sandbox Code Playgroud)

ghci> (+) <<$>> [Just 5] <<*>> [Just 7,Just 10]
[Just 12,Just 15]
Run Code Online (Sandbox Code Playgroud)

当然,你可以坚持下去:

(<<<$>>>) :: (Functor f, Functor g, Functor h) => 
             (a -> b) -> f (g (h a)) -> f (g (h b))
(<<<$>>>) = fmap.fmap.fmap

(<<<*>>>) :: (Functor l,Functor m, Applicative l, Applicative m, Applicative n) =>
             l (m (n (a -> b))) -> l (m (n a)) -> l (m (n b))
lmnf <<<*>>> lmna = (<*>) <<$>> lmnf <<*>> lmna
Run Code Online (Sandbox Code Playgroud)

这让你做的显然不太可能

ghci> subtract <<<$>>> Right [Just 5,Nothing,Just 10] <<<*>>> Right [Just 100,Just 20]
Right [Just 95,Just 15,Nothing,Nothing,Just 90,Just 10]
Run Code Online (Sandbox Code Playgroud)

但是再次,正如Gershom Bazerman的文章所示,你可能想要嵌套Applicatives,就像你想要嵌套Monads一样深.