{-# LANGUAGE AllowAmbiguousTypes #-}

module Generic.Data.Function.Example where

import GHC.Generics
import Generic.Data.Function.FoldMap
import Generic.Data.Rep.Assert

import Data.List qualified as List

--data D a = D1 a | D2 a a deriving stock (Generic, Show)
data X = X1 | X2 deriving stock (forall x. Rep X x -> X
forall x. X -> Rep X x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep X x -> X
$cfrom :: forall x. X -> Rep X x
Generic)
data Y = Y deriving stock (forall x. Rep Y x -> Y
forall x. Y -> Rep Y x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Y x -> Y
$cfrom :: forall x. Y -> Rep Y x
Generic)

newtype Showly = Showly { Showly -> [String]
unShowly :: [String] }
    --deriving Show via String
    deriving (NonEmpty Showly -> Showly
Showly -> Showly -> Showly
forall b. Integral b => b -> Showly -> Showly
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> Showly -> Showly
$cstimes :: forall b. Integral b => b -> Showly -> Showly
sconcat :: NonEmpty Showly -> Showly
$csconcat :: NonEmpty Showly -> Showly
<> :: Showly -> Showly -> Showly
$c<> :: Showly -> Showly -> Showly
Semigroup, Semigroup Showly
Showly
[Showly] -> Showly
Showly -> Showly -> Showly
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [Showly] -> Showly
$cmconcat :: [Showly] -> Showly
mappend :: Showly -> Showly -> Showly
$cmappend :: Showly -> Showly -> Showly
mempty :: Showly
$cmempty :: Showly
Monoid) via [String]

instance GenericFoldMap Showly where
    type GenericFoldMapC Showly a = Show a
    genericFoldMapF :: forall a. GenericFoldMapC Showly a => a -> Showly
genericFoldMapF = [String] -> Showly
Showly forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\String
a -> [String
a]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show

showGeneric
    :: forall {cd} {f} opts asserts a
    .  (Generic a, Rep a ~ D1 cd f, GFoldMapSum opts Showly f, ApplyGCAsserts asserts f)
    => a -> String
showGeneric :: forall {cd :: Meta} {f :: Type -> Type} (opts :: SumOpts)
       (asserts :: [GCAssert]) a.
(Generic a, Rep a ~ D1 cd f, GFoldMapSum opts Showly f,
 ApplyGCAsserts asserts f) =>
a -> String
showGeneric =
      forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
List.intersperse String
" " forall b c a. (b -> c) -> (a -> b) -> a -> c
. Showly -> [String]
unShowly
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {cd :: Meta} {f :: Type -> Type} (opts :: SumOpts)
       (asserts :: [GCAssert]) m a.
(Generic a, Rep a ~ D1 cd f, GFoldMapSum opts m f,
 ApplyGCAsserts asserts f) =>
(String -> m) -> a -> m
genericFoldMapSum @opts @asserts (\String
cstr -> [String] -> Showly
Showly [String
cstr])

showGeneric'
    :: forall {cd} {f} asserts a
    .  (Generic a, Rep a ~ D1 cd f, GFoldMapNonSum Showly f, ApplyGCAsserts asserts f)
    => a -> String
showGeneric' :: forall {cd :: Meta} {f :: Type -> Type} (asserts :: [GCAssert]) a.
(Generic a, Rep a ~ D1 cd f, GFoldMapNonSum Showly f,
 ApplyGCAsserts asserts f) =>
a -> String
showGeneric' =
    forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
List.intersperse String
" " forall b c a. (b -> c) -> (a -> b) -> a -> c
. Showly -> [String]
unShowly forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {cd :: Meta} {f :: Type -> Type} (asserts :: [GCAssert]) m
       a.
(Generic a, Rep a ~ D1 cd f, GFoldMapNonSum m f,
 ApplyGCAsserts asserts f) =>
a -> m
genericFoldMapNonSum @asserts