找不到类似liftM2的功能

ais*_*ais 5 monads haskell

myLiftM2 ::  Monad m => (a -> a1 -> m b) -> m a -> m a1 -> m b
myLiftM2 f x y = x >>= (\r1 -> y >>= (\r2 -> f r1 r2))
Run Code Online (Sandbox Code Playgroud)

在liftM2中f返回b,但myLiftM2返回mb

ami*_*dfv 6

tl; dr:使用,join :: Monad m => m (m a) -> m a因为普通电梯将返回m (m a).比如写

join $ liftM2 f a b
Run Code Online (Sandbox Code Playgroud)

但是也...

liftMs也可以用Applicative- 例如

liftM2 a b c   == a <$> b <*> c
liftM3 a b c d == a <$> b <*> c <*> d
Run Code Online (Sandbox Code Playgroud)

等等

在这种情况下,如果您愿意以这种方式书写,您可以干净利落地编写它:

import Control.Applicative

myLiftM2 :: (Monad m, Applicative m) => (a -> a1 -> m b) -> m a -> m a1 -> m b
myLiftM2 f x y = join $ f <$> x <*> y
Run Code Online (Sandbox Code Playgroud)

编辑:
正如Daniel Wagner指出的那样,你可以轻松地写出来

join $ liftM2 a b c
Run Code Online (Sandbox Code Playgroud)

作为等价物

join $ a <$> b <*> c
Run Code Online (Sandbox Code Playgroud)

我对应用风格的建议是为了便于阅读,并且是一个单独的观点.

  • 如果你打算使用`join`,你就可以在没有其他风格的情况下做到这一点:`myLiftM2 fxy = join $ liftM2 fxy`. (2认同)