aeson-extra-0.3.2.0: src/Data/Aeson/Extra/Merge.hs
{-# LANGUAGE RankNTypes #-}
-----------------------------------------------------------------------------
-- |
-- Module : Data.Aeson.Extra.Merge
-- Copyright : (C) 2015-2016 Oleg Grenrus
-- License : BSD3
-- Maintainer : Oleg Grenrus <oleg.grenrus@iki.fi>
--
module Data.Aeson.Extra.Merge (
merge,
mergeA,
ValueF(..),
ObjectF,
ArrayF,
) where
import Prelude ()
import Prelude.Compat
import Data.Aeson.Compat
import Data.Aeson.Extra.Foldable
import Data.Functor.Foldable (project, embed)
-- | Generic merge.
--
-- For example <https://lodash.com/docs#merge>:
--
-- @
-- lodashMerge :: Value -> Value -> Value
-- lodashMerge x y = merge lodashMergeAlg x y
--
-- lodashMergeAlg :: (a -> a -> a) -> ValueF a -> ValueF a -> ValueF a
-- lodashMergeAlg r a' b' = case (a', b') of
-- (ObjectF a, ObjectF b) -> ObjectF $ alignWith f a b
-- (ArrayF a, ArrayF b) -> ArrayF $ alignWith f a b
-- (_, b) -> b
-- where f (These x y) = r x y
-- f (This x) = x
-- f (That x) = x
-- @
--
-- /Since: aeson-extra-0.3.1.0/
merge :: (forall a. (a -> a -> a) -> ValueF a -> ValueF a -> ValueF a)
-> Value -> Value -> Value
merge f a b = embed $ f (merge f) (project a) (project b)
-- | Generic merge, in arbitrary context.
--
-- /Since: aeson-extra-0.3.1.0/
mergeA :: Functor f
=> (forall a. (a -> a -> f a) -> ValueF a -> ValueF a -> f (ValueF a))
-> Value -> Value -> f Value
mergeA f a b = embed <$> f (mergeA f) (project a) (project b)