【发布时间】:2016-05-08 04:37:34
【问题描述】:
我试图写一个类似于Data.Map.unionWith的函数,但可能会失败。原来的使用 Maybe,它确实是 Monad,所以 monadic 对我来说很好用。但我想知道它是否可以用 Applicative 重写,因为我用 pure 映射它只是为了满足 unionWith 的类型要求。或者在 Data.Map 中使用其他函数而不是 unionWith?
{-# 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 -> m v的v结果提供给v -> v -> m v的另一个调用。这与需要单子的 Kelisli 组合很接近。
标签: haskell dictionary monads applicative