{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE CPP #-}
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Safe #-}
#endif
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
{-# LANGUAGE PolyKinds #-}
#endif
module Data.GADT.Show where

-- |'Show'-like class for 1-type-parameter GADTs.  @GShow t => ...@ is equivalent to something
-- like @(forall a. Show (t a)) => ...@.  The easiest way to create instances would probably be
-- to write (or derive) an @instance Show (T a)@, and then simply say:
--
-- > instance GShow t where gshowsPrec = showsPrec
class GShow t where
    gshowsPrec :: Int -> t a -> ShowS


gshows :: GShow t => t a -> ShowS
gshows :: t a -> ShowS
gshows = Int -> t a -> ShowS
forall k (t :: k -> *) (a :: k). GShow t => Int -> t a -> ShowS
gshowsPrec (-1)

gshow :: (GShow t) => t a -> String
gshow :: t a -> String
gshow x :: t a
x = t a -> ShowS
forall k (t :: k -> *) (a :: k). GShow t => t a -> ShowS
gshows t a
x ""

newtype GReadResult t = GReadResult
  { GReadResult t -> forall b. (forall (a :: k). t a -> b) -> b
getGReadResult :: forall b . (forall a . t a -> b) -> b }

-- |@GReadS t@ is equivalent to @ReadS (forall b. (forall a. t a -> b) -> b)@, which is 
-- in turn equivalent to @ReadS (Exists t)@ (with @data Exists t where Exists :: t a -> Exists t@)
type GReadS t = String -> [(GReadResult t, String)]

-- |'Read'-like class for 1-type-parameter GADTs.  Unlike 'GShow', this one cannot be 
-- mechanically derived from a 'Read' instance because 'greadsPrec' must choose the phantom
-- type based on the 'String' being parsed.
class GRead t where
    greadsPrec :: Int -> GReadS t

greads :: GRead t => GReadS t
greads :: GReadS t
greads = Int -> GReadS t
forall k (t :: k -> *). GRead t => Int -> GReadS t
greadsPrec (-1)

gread :: GRead t => String -> (forall a. t a -> b) -> b
gread :: String -> (forall (a :: k). t a -> b) -> b
gread s :: String
s g :: forall (a :: k). t a -> b
g = case [GReadResult t] -> GReadResult t
forall p. [p] -> p
hd [GReadResult t
f | (f :: GReadResult t
f, "") <- GReadS t
forall k (t :: k -> *). GRead t => GReadS t
greads String
s] of
              GReadResult res :: forall b. (forall (a :: k). t a -> b) -> b
res -> (forall (a :: k). t a -> b) -> b
forall b. (forall (a :: k). t a -> b) -> b
res forall (a :: k). t a -> b
g
    where
        hd :: [p] -> p
hd (x :: p
x:_) = p
x
        hd _ = String -> p
forall a. HasCallStack => String -> a
error "gread: no parse"