我試圖編寫一個類似於Data.Map.unionWith的函數,但可能會失敗。原來的那個使用了Maybe,它確實是一個Monad,所以這個Monadic對我來說工作得很好。但我想知道它是否可以用Applicative重寫,因爲我用純的方法來映射它,只是爲了滿足unionWith的類型需求。或者與Data.Map中的其他函數而不是unionWith?我可以用Applicative而不是Monad來重寫這個unionWith-like函數嗎?
{-# LANGUAGE RankNTypes #-}
import Control.Monad
import Data.Map
unionWithM :: (Monad m, Traversable t)
=> (forall a. (a -> a -> a)
-> t a
-> t a
-> t a
)
-> (v -> v -> m v)
-> t v
-> t v
-> m (t v)
unionWithM u f a b = sequenceA (u f' (pure <$> a) (pure <$> b))
where f' x y = join $ f <$> x <*> y
unionWithOriginal :: Ord k => (a -> a -> Maybe a) -> Map k a -> Map k a -> Maybe (Map k a)
unionWithOriginal f a b = sequenceA (unionWith f' (Just <$> a) (Just <$> b))
where f' x y = join $ f <$> x <*> y
AFAICS,'unionWithM'是不可能的:'unionWith'可以養活'v'結果'v - > v - > mv'到另一個'v - > v - > mv'調用。這接近Kelisli組合,它需要monads。 – chi