myLiftM2 :: Monad m => (a -> a1 -> m b) -> m a -> m a1 -> m b
myLiftM2 f x y = x >>= (\r1 -> y >>= (\r2 -> f r1 r2))
在liftM2˚F回報B功能,但myLiftM2返回M B找不到類似liftM2
myLiftM2 :: Monad m => (a -> a1 -> m b) -> m a -> m a1 -> m b
myLiftM2 f x y = x >>= (\r1 -> y >>= (\r2 -> f r1 r2))
在liftM2˚F回報B功能,但myLiftM2返回M B找不到類似liftM2
TL;博士:使用join :: Monad m => m (m a) -> m a
,因爲一個普通的電梯將返回m (m a)
。例如。寫
join $ liftM2 f a b
而且...
liftM
S可也可與Applicative
寫 - 例如
liftM2 a b c == a <$> b <*> c
liftM3 a b c d == a <$> b <*> c <*> d
等
在這種情況下,如果你願意在風格來寫,你可以乾淨,容易寫:
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
編輯:
作爲丹尼爾瓦格納指出,你可以輕鬆地寫
join $ liftM2 a b c
的應用性風格的等效
join $ a <$> b <*> c
我的建議是可讀性,是一個獨立的點。
如果你打算使用'join',你可以在不對其他樣式進行離題的情況下做到這一點:'myLiftM2 f x y = join $ liftM2 f x y'。 –
真的 - 我想我推薦使用連接和獨立使用應用樣式 – amindfv
它在實際中並不經常出現,而且用'liftM2'和'join'方式編寫很簡單:'myLiftM2 =((join。)。)。 liftM2'。 – is7s
is7s,我不同意。我已經在練習中多次碰到這個函數,但我通常使用符號而不是使用函數。 – augustss
這在Control.Monad.Parallel中稱爲'bindM2'。 –