hkt-0.0.1: src/HKT/Merge.hs
module HKT.Merge (Merge, merge) where
import Protolude
import HKT.Type (ID)
import GHC.Generics (Generic, Rep, M1(M1), K1(K1), V1, U1, from, to, (:*:)((:*:)))
import qualified Data.Maybe
class Merge a where
merge :: a ID -> a Maybe -> a ID
default merge ::
( Generic (a Maybe)
, Generic (a ID)
, GMerge (Rep (a ID)) (Rep (a Maybe))
) => a ID -> a Maybe -> a ID
merge a b = to $ gmerge (from a ) (from b)
class GMerge a b where
gmerge :: a p -> b p -> a p
instance GMerge a b => GMerge (M1 i c a) (M1 i c b) where
gmerge (M1 a) (M1 b) = M1 $ gmerge a b
{-# INLINE gmerge #-}
instance (GMerge a b, GMerge c d) => GMerge (a :*: c) (b :*: d) where
gmerge (a :*: c) (b :*: d) = gmerge a b :*: gmerge c d
{-# INLINE gmerge #-}
instance GMerge (K1 a k) (K1 a (Maybe k)) where
gmerge (K1 a) (K1 ma) = K1 $ Data.Maybe.fromMaybe a ma
{-# INLINE gmerge #-}
instance GMerge U1 U1 where
gmerge U1 _ = U1
{-# INLINE gmerge #-}
instance GMerge V1 V1 where
gmerge _ = (\case {})
{-# INLINE gmerge #-}