{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Singletons.Prelude.Show (
PShow(..), SShow(..), SymbolS, SChar, show_,
type (<>), (%<>),
Shows, sShows,
ShowListWith, sShowListWith,
ShowChar, sShowChar,
ShowString, sShowString,
ShowParen, sShowParen,
ShowSpace, sShowSpace,
ShowCommaSpace, sShowCommaSpace,
AppPrec, sAppPrec,
AppPrec1, sAppPrec1,
ShowsPrecSym0, ShowsPrecSym1, ShowsPrecSym2, ShowsPrecSym3,
Show_Sym0, Show_Sym1,
ShowListSym0, ShowListSym1, ShowListSym2,
type (<>@#@$), type (<>@#@$$), type (<>@#@$$$),
ShowsSym0, ShowsSym1, ShowsSym2,
ShowListWithSym0, ShowListWithSym1, ShowListWithSym2, ShowListWithSym3,
ShowCharSym0, ShowCharSym1, ShowCharSym2,
ShowStringSym0, ShowStringSym1, ShowStringSym2,
ShowParenSym0, ShowParenSym1, ShowParenSym2,
ShowSpaceSym0, ShowSpaceSym1,
ShowCommaSpaceSym0, ShowCommaSpaceSym1,
AppPrecSym0, AppPrec1Sym0
) where
import Data.List.NonEmpty (NonEmpty)
import Data.Proxy
import Data.Singletons.Internal
import Data.Singletons.Prelude.Base
import Data.Singletons.Prelude.Instances
import Data.Singletons.Prelude.List
import Data.Singletons.Prelude.Ord
import Data.Singletons.Promote
import Data.Singletons.Single
import Data.Singletons.TypeLits
import qualified Data.Text as T
import Data.Void
import GHC.TypeLits
import qualified Prelude as P
import Prelude hiding (Show(..))
import Unsafe.Coerce (unsafeCoerce)
type SymbolS = Symbol -> Symbol
type SChar = Symbol
$(singletonsOnly [d|
class Show a where
showsPrec :: Nat -> a -> SymbolS
show_ :: a -> Symbol
showList :: [a] -> SymbolS
showsPrec _ x s = show_ x <> s
show_ x = shows x ""
showList ls s = showListWith shows ls s
shows :: Show a => a -> SymbolS
shows s = showsPrec 0 s
showListWith :: (a -> SymbolS) -> [a] -> SymbolS
showListWith _ [] s = "[]" <> s
showListWith showx (x:xs) s = "[" <> showx x (showl xs)
where
showl [] = "]" <> s
showl (y:ys) = "," <> showx y (showl ys)
showChar :: SChar -> SymbolS
showChar = (<>)
showString :: Symbol -> SymbolS
showString = (<>)
showParen :: Bool -> SymbolS -> SymbolS
showParen b p = if b then showChar "(" . p . showChar ")" else p
showSpace :: SymbolS
showSpace = \xs -> " " <> xs
showCommaSpace :: SymbolS
showCommaSpace = showString ", "
appPrec, appPrec1 :: Nat
appPrec = 10
appPrec1 = 11
instance Show a => Show [a] where
showsPrec _ = showList
instance Show Symbol where
showsPrec _ = showString
show_tuple :: [SymbolS] -> SymbolS
show_tuple ss = showChar "("
. foldr1 (\s r -> s . showChar "," . r) ss
. showChar ")"
instance (Show a, Show b) => Show (a,b) where
showsPrec _ (a,b) s = show_tuple [shows a, shows b] s
instance (Show a, Show b, Show c) => Show (a, b, c) where
showsPrec _ (a,b,c) s = show_tuple [shows a, shows b, shows c] s
instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
showsPrec _ (a,b,c,d) s = show_tuple [shows a, shows b, shows c, shows d] s
instance (Show a, Show b, Show c, Show d, Show e) => Show (a, b, c, d, e) where
showsPrec _ (a,b,c,d,e) s = show_tuple [shows a, shows b, shows c, shows d, shows e] s
instance (Show a, Show b, Show c, Show d, Show e, Show f) => Show (a,b,c,d,e,f) where
showsPrec _ (a,b,c,d,e,f) s = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f] s
instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g)
=> Show (a,b,c,d,e,f,g) where
showsPrec _ (a,b,c,d,e,f,g) s
= show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g] s
|])
$(promoteOnly [d|
showsNat :: Nat -> SymbolS
showsNat 0 = showChar "0"
showsNat 1 = showChar "1"
showsNat 2 = showChar "2"
showsNat 3 = showChar "3"
showsNat 4 = showChar "4"
showsNat 5 = showChar "5"
showsNat 6 = showChar "6"
showsNat 7 = showChar "7"
showsNat 8 = showChar "8"
showsNat 9 = showChar "9"
showsNat n = showsNat (n `div` 10) . showsNat (n `mod` 10)
|])
instance PShow Nat where
type ShowsPrec _ n x = ShowsNat n x
instance SShow Nat where
sShowsPrec _ sn sx =
let n = fromSing sn
x = fromSing sx
ex = someSymbolVal (P.show n ++ T.unpack x)
in
case ex of
SomeSymbol (_ :: Proxy s) -> unsafeCoerce (SSym :: Sing s)
show_ :: P.Show a => a -> String
show_ = P.show
$(singShowInstances [ ''(), ''Maybe, ''Either, ''NonEmpty, ''Bool,
''Ordering, ''Void ])