generic-data-functions-0.4.1: src/Generic/Data/Function/Traverse.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{- | 'traverse' for generic data types.
TODO This is harder to conceptualize than generic 'foldMap'. No nice clean
explanation yet.
This function can provide generic support for simple parser-esque types.
-}
module Generic.Data.Function.Traverse
( GenericTraverse(..)
, genericTraverseNonSum , GTraverseNonSum
, GenericTraverseSum(..), PfxTagCfg(..)
, genericTraverseSum, GTraverseSum
, eqShowPfxTagCfg
) where
import GHC.Generics
import Generic.Data.Function.Traverse.NonSum
import Generic.Data.Function.Traverse.Sum
import Generic.Data.Function.Traverse.Constructor
import Data.Text qualified as Text
-- | Generic 'traverse' over a term of non-sum data type @f a@,
-- where @f@ is set by the @tag@ you pass.
genericTraverseNonSum
:: forall {k} (tag :: k) a
. ( Generic a
, Functor (GenericTraverseF tag)
, GTraverseNonSum tag (Rep a)
) => GenericTraverseF tag a
genericTraverseNonSum = to <$> gTraverseNonSum @tag
-- | Generic 'traverse' over a term of sum data type @f a@,
-- where @f@ is set by the @tag@ you pass.
--
-- You must provide a configuration for how to handle constructors.
genericTraverseSum
:: forall {k} (tag :: k) opts a pt
. ( Generic a
, Functor (GenericTraverseF tag)
, GTraverseSum tag opts (Rep a)
, GenericTraverseC tag pt
) => PfxTagCfg pt -> GenericTraverseF tag a
genericTraverseSum ptc = to <$> gTraverseSum @tag @opts ptc
-- | Construct a prefix tag config using existing 'Eq' and 'Show' instances.
--
-- The user only needs to provide the constructor name parser.
eqShowPfxTagCfg :: (Eq a, Show a) => (String -> a) -> PfxTagCfg a
eqShowPfxTagCfg f = PfxTagCfg
{ pfxTagCfgFromCstr = f
, pfxTagCfgEq = (==)
, pfxTagCfgShow = Text.pack . show
}