{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE Safe #-}
module Generic.Data.Internal.Show where
import Data.Foldable (foldl')
import Data.Functor.Classes (Show1(..))
import Data.Functor.Identity
import Data.Proxy
import GHC.Generics
import Text.Show.Combinators
gshowsPrec :: (Generic a, GShow0 (Rep a)) => Int -> a -> ShowS
gshowsPrec = flip gprecShows
gprecShows :: (Generic a, GShow0 (Rep a)) => a -> PrecShowS
gprecShows = gPrecShows Proxy . from
type GShow0 = GShow Proxy
gliftShowsPrec
:: (Generic1 f, GShow1 (Rep1 f))
=> (Int -> a -> ShowS) -> ([a] -> ShowS)
-> Int -> f a -> ShowS
gliftShowsPrec showsPrec' showList' =
flip (gLiftPrecShows showsPrec' showList' . from1)
gLiftPrecShows
:: GShow1 f
=> (Int -> a -> ShowS) -> ([a] -> ShowS)
-> f a -> PrecShowS
gLiftPrecShows = curry (gPrecShows . Identity)
type ShowsPrec a = (Int -> a -> ShowS, [a] -> ShowS)
type GShow1 = GShow Identity
class GShow p f where
gPrecShows :: p (ShowsPrec a) -> f a -> PrecShowS
instance GShow p f => GShow p (M1 D d f) where
gPrecShows p (M1 x) = gPrecShows p x
instance (GShow p f, GShow p g) => GShow p (f :+: g) where
gPrecShows p (L1 x) = gPrecShows p x
gPrecShows p (R1 y) = gPrecShows p y
instance (Constructor c, GShowC p c f) => GShow p (M1 C c f) where
gPrecShows p x = gPrecShowsC p (conName x) (conFixity x) x
instance GShow p V1 where
gPrecShows _ v = case v of {}
class GShowC p c f where
gPrecShowsC :: p (ShowsPrec a) -> String -> Fixity -> M1 C c f a -> PrecShowS
instance GShowFields p f => GShowC p ('MetaCons s y 'False) f where
gPrecShowsC p name fixity (M1 x)
| Infix _ fy <- fixity, k1 : k2 : ks <- fields =
foldl' showApp (showInfix name fy k1 k2) ks
| otherwise = foldl' showApp (showCon cname) fields
where
cname = case fixity of
Prefix -> name
Infix _ _ -> "(" ++ name ++ ")"
fields = gPrecShowsFields p x
instance GShowNamed p f => GShowC p ('MetaCons s y 'True) f where
gPrecShowsC p name fixity (M1 x) = showRecord cname fields
where
cname = case fixity of
Prefix -> name
Infix _ _ -> "(" ++ name ++ ")"
fields = gPrecShowsNamed p x
class GShowFields p f where
gPrecShowsFields :: p (ShowsPrec a) -> f a -> [PrecShowS]
instance (GShowFields p f, GShowFields p g) => GShowFields p (f :*: g) where
gPrecShowsFields p (x :*: y) = gPrecShowsFields p x ++ gPrecShowsFields p y
instance GShowSingle p f => GShowFields p (M1 S c f) where
gPrecShowsFields p (M1 x) = [gPrecShowsSingle p x]
instance GShowFields p U1 where
gPrecShowsFields _ U1 = []
class GShowNamed p f where
gPrecShowsNamed :: p (ShowsPrec a) -> f a -> ShowFields
instance (GShowNamed p f, GShowNamed p g) => GShowNamed p (f :*: g) where
gPrecShowsNamed p (x :*: y) = gPrecShowsNamed p x &| gPrecShowsNamed p y
instance (Selector c, GShowSingle p f) => GShowNamed p (M1 S c f) where
gPrecShowsNamed p x'@(M1 x) = selName x' `showField` gPrecShowsSingle p x
instance GShowNamed p U1 where
gPrecShowsNamed _ U1 = noFields
class GShowSingle p f where
gPrecShowsSingle :: p (ShowsPrec a) -> f a -> PrecShowS
instance Show a => GShowSingle p (K1 i a) where
gPrecShowsSingle _ (K1 x) = flip showsPrec x
instance Show1 f => GShowSingle Identity (Rec1 f) where
gPrecShowsSingle (Identity sp) (Rec1 r) =
flip (uncurry liftShowsPrec sp) r
instance GShowSingle Identity Par1 where
gPrecShowsSingle (Identity (showsPrec', _)) (Par1 a) = flip showsPrec' a
instance (Show1 f, GShowSingle p g)
=> GShowSingle p (f :.: g) where
gPrecShowsSingle p (Comp1 c) =
flip (liftShowsPrec showsPrec_ showList_) c
where
showsPrec_ = flip (gPrecShowsSingle p)
showList_ = showListWith (showsPrec_ 0)