Is it possible to rewrite this unionWith-like function with Applicative instead of Monad?

I tried to write a function similar to Data.Map.unionWith , but may fail. The original uses “Maybe”, which is really a monad, so a monadic project is great for me. but I am wondering if it can be rewritten with Applicative, since I used it only to satisfy a requirement like unionWith. Or with another function in Data.Map instead of 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
+4
source share
1 answer

, , . , , f' m a -> m a -> m a. f f', join, Monad. , . (Maybe a, Maybe a), , These. ,

data These a b = That a | This b | These a b

unionWith' f a b = let theses = unionWith These (That <$> a) (This <$> b)
                   in sequenceA (f' <$> theses)
    where f' (That a) = pure a
          f' (This b) = pure b
          f' (These a b) = f a b

these,

 unionWith'' f a b = sequenceA $ alignWith (these pure pure f)  a b
+7

All Articles