2013-11-23 47 views
4
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

+1

它在實際中並不經常出現,而且用'liftM2'和'join'方式編寫很簡單:'myLiftM2 =((join。)。)。 liftM2'。 – is7s

+4

is7s,我不同意。我已經在練習中多次碰到這個函數,但我通常使用符號而不是使用函數。 – augustss

+0

這在Control.Monad.Parallel中稱爲'bindM2'。 –

回答

5

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 

我的建議是可讀性,是一個獨立的點。

+2

如果你打算使用'join',你可以在不對其他樣式進行離題的情況下做到這一點:'myLiftM2 f x y = join $ liftM2 f x y'。 –

+0

真的 - 我想我推薦使用連接和獨立使用應用樣式 – amindfv