{-# LANGUAGE MultiParamTypeClasses, OverloadedStrings #-}

-- |Module `ShowInfo` include class `ShowInfo` for pretty printing of objects
--  in this project.
module ShowInfo (
    Title (Title),
    WithTitle,
    withTitle,
    title,
    withoutTitle,
    ShowInfo (..),
  ) where

import TuringMachine
import SemigroupPresentation as SP
import GroupPresentation as GP
import GrammarType
import GRType
import TMType

import Control.Lens (imap)
import Data.List (intercalate)
import Data.String (IsString (fromString))

newtype Title = Title String
    deriving (Title -> Title -> Bool
(Title -> Title -> Bool) -> (Title -> Title -> Bool) -> Eq Title
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Title -> Title -> Bool
$c/= :: Title -> Title -> Bool
== :: Title -> Title -> Bool
$c== :: Title -> Title -> Bool
Eq, Eq Title
Eq Title
-> (Title -> Title -> Ordering)
-> (Title -> Title -> Bool)
-> (Title -> Title -> Bool)
-> (Title -> Title -> Bool)
-> (Title -> Title -> Bool)
-> (Title -> Title -> Title)
-> (Title -> Title -> Title)
-> Ord Title
Title -> Title -> Bool
Title -> Title -> Ordering
Title -> Title -> Title
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Title -> Title -> Title
$cmin :: Title -> Title -> Title
max :: Title -> Title -> Title
$cmax :: Title -> Title -> Title
>= :: Title -> Title -> Bool
$c>= :: Title -> Title -> Bool
> :: Title -> Title -> Bool
$c> :: Title -> Title -> Bool
<= :: Title -> Title -> Bool
$c<= :: Title -> Title -> Bool
< :: Title -> Title -> Bool
$c< :: Title -> Title -> Bool
compare :: Title -> Title -> Ordering
$ccompare :: Title -> Title -> Ordering
$cp1Ord :: Eq Title
Ord)

instance Show Title where
    show :: Title -> String
show (Title String
t) = String
t

instance IsString Title where
    fromString :: String -> Title
fromString = String -> Title
Title

newtype WithTitle a = WT (Title, a)

instance Insertable Title Char where
    insert :: Char -> Title -> m Title
insert = (((Title -> Title) -> Title -> m Title)
-> (Char -> Title -> Title) -> Char -> Title -> m Title
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap(((Title -> Title) -> Title -> m Title)
 -> (Char -> Title -> Title) -> Char -> Title -> m Title)
-> ((Title -> m Title) -> (Title -> Title) -> Title -> m Title)
-> (Title -> m Title)
-> (Char -> Title -> Title)
-> Char
-> Title
-> m Title
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Title -> m Title) -> (Title -> Title) -> Title -> m Title
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) Title -> m Title
forall (m :: * -> *) a. Monad m => a -> m a
return Char -> Title -> Title
forall c v. Insertable c v => v -> c -> c
unsafeInsert
    unsafeInsert :: Char -> Title -> Title
unsafeInsert Char
c (Title String
t) = String -> Title
Title (String -> Title) -> String -> Title
forall a b. (a -> b) -> a -> b
$ Char
c Char -> ShowS
forall a. a -> [a] -> [a]
: String
t
    (Title String
t) <+ :: Title -> Char -> Title
<+ Char
c = String -> Title
Title (String -> Title) -> String -> Title
forall a b. (a -> b) -> a -> b
$ String
t String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char
c]

withTitle :: Title -> a -> WithTitle a
withTitle :: Title -> a -> WithTitle a
withTitle = ((Title, a) -> WithTitle a) -> Title -> a -> WithTitle a
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (Title, a) -> WithTitle a
forall a. (Title, a) -> WithTitle a
WT

title :: WithTitle a -> Title
title :: WithTitle a -> Title
title (WT (Title
t, a
_)) = Title
t

withoutTitle :: WithTitle a -> a
withoutTitle :: WithTitle a -> a
withoutTitle (WT (Title
_, a
a)) = a
a

class ShowInfo a where
    showTitle :: a -> Title
    showInfo :: a -> String
    showTitleAndInfo :: a -> String
    showTitleAndInfo a
a =
        Title -> ShowS
addTitleWithNewLine (a -> Title
forall a. ShowInfo a => a -> Title
showTitle a
a) (a -> String
forall a. ShowInfo a => a -> String
showInfo a
a)
    showListTitle :: [a] -> Title
    showListTitle = Title -> [a] -> Title
forall a b. a -> b -> a
const Title
"List"
    showListInfo :: [a] -> String
    showListInfo [a]
as =
        let titleLength :: Int
titleLength = String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show (Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$ [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
as Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
            prettyShowNum :: a -> Title
prettyShowNum a
n =
                let nAsStr :: String
nAsStr = a -> String
forall a. Show a => a -> String
show a
n
                in  String -> Title
Title (String -> Title) -> String -> Title
forall a b. (a -> b) -> a -> b
$
                        String
nAsStr String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
titleLength Int -> Int -> Int
forall a. Num a => a -> a -> a
- String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
nAsStr) Char
' '
        in  [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$
                (Int -> a -> String) -> [a] -> [String]
forall i (f :: * -> *) a b.
FunctorWithIndex i f =>
(i -> a -> b) -> f a -> f b
imap (\Int
i a
a ->
                    Title -> ShowS
addTitleWithoutNewLine (Int -> Title
forall a. Show a => a -> Title
prettyShowNum Int
i) (a -> String
forall a. ShowInfo a => a -> String
showInfo a
a)
                  ) [a]
as

addTitleWithNewLine :: Title -> String -> String
addTitleWithNewLine :: Title -> ShowS
addTitleWithNewLine (Title String
t) =
    ((String
t String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
":\n") String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
unlines ([String] -> String) -> (String -> [String]) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String
"    " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ) ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines

addTitleWithoutNewLine :: Title -> String -> String
addTitleWithoutNewLine :: Title -> ShowS
addTitleWithoutNewLine (Title String
t) =
    [String] -> String
unlines ([String] -> String) -> (String -> [String]) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    (Int -> ShowS) -> [String] -> [String]
forall i (f :: * -> *) a b.
FunctorWithIndex i f =>
(i -> a -> b) -> f a -> f b
imap (\Int
i -> String -> ShowS
forall a. [a] -> [a] -> [a]
(++) (
        if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
        then String
t String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": "
        else Int -> Char -> String
forall a. Int -> a -> [a]
replicate (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
t Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Char
' '
      )) ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    String -> [String]
lines

instance ShowInfo Char where
    showTitle :: Char -> Title
showTitle = Title -> Char -> Title
forall a b. a -> b -> a
const Title
"Char"
    showInfo :: Char -> String
showInfo = Char -> String
forall a. Show a => a -> String
show
    showListTitle :: String -> Title
showListTitle = Title -> String -> Title
forall a b. a -> b -> a
const Title
"String"
    showListInfo :: ShowS
showListInfo = ShowS
forall a. a -> a
id

instance ShowInfo Grammar where
    showTitle :: Grammar -> Title
showTitle = Title -> Grammar -> Title
forall a b. a -> b -> a
const Title
"Grammar"
    showInfo :: Grammar -> String
showInfo (Grammar (Set Nonterminal
ns, Set Terminal
ts, Set Relation
rs, Nonterminal
_)) = ShowS -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n") [
        String
"nonterminals: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Set Nonterminal -> Int
forall c. Sizable c => c -> Int
size Set Nonterminal
ns),
        String
"terminals: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Set Terminal -> Int
forall c. Sizable c => c -> Int
size Set Terminal
ts),
        String
"relations: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Set Relation -> Int
forall c. Sizable c => c -> Int
size Set Relation
rs)
      ]
    showListTitle :: [Grammar] -> Title
showListTitle = Title -> [Grammar] -> Title
forall a b. a -> b -> a
const Title
"List of Grammars"

instance ShowInfo TuringMachine where
    showTitle :: TuringMachine -> Title
showTitle = Title -> TuringMachine -> Title
forall a b. a -> b -> a
const Title
"Turing Machine"
    showInfo :: TuringMachine -> String
showInfo TuringMachine
tm = ShowS -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n") [
        String
"states: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (TuringMachine
tmTuringMachine -> Getting Int TuringMachine Int -> Int
forall s a. s -> Getting a s a -> a
^.(Set State -> Const Int (Set State))
-> TuringMachine -> Const Int TuringMachine
TMGetter (Set State)
allStates((Set State -> Const Int (Set State))
 -> TuringMachine -> Const Int TuringMachine)
-> ((Int -> Const Int Int) -> Set State -> Const Int (Set State))
-> Getting Int TuringMachine Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Set State -> Int)
-> (Int -> Const Int Int) -> Set State -> Const Int (Set State)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to(Set State -> Int
forall c. Sizable c => c -> Int
size)),
        String
"symbols: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (TuringMachine
tmTuringMachine -> Getting Int TuringMachine Int -> Int
forall s a. s -> Getting a s a -> a
^.(Set Symbol -> Const Int (Set Symbol))
-> TuringMachine -> Const Int TuringMachine
TMGetter (Set Symbol)
allSymbols((Set Symbol -> Const Int (Set Symbol))
 -> TuringMachine -> Const Int TuringMachine)
-> ((Int -> Const Int Int) -> Set Symbol -> Const Int (Set Symbol))
-> Getting Int TuringMachine Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Set Symbol -> Int)
-> (Int -> Const Int Int) -> Set Symbol -> Const Int (Set Symbol)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to(Set Symbol -> Int
forall c. Sizable c => c -> Int
size)) String -> ShowS
forall a. [a] -> [a] -> [a]
++
            String
" (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " (Set String -> [String]
forall c v. Listable c v => c -> [v]
toList (TuringMachine
tmTuringMachine
-> Getting (Set String) TuringMachine (Set String) -> Set String
forall s a. s -> Getting a s a -> a
^.Getting (Set String) TuringMachine (Set String)
TMGetter (Set String)
strSymbols)) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")",
        String
"quadruples: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (TuringMachine
tmTuringMachine -> Getting Int TuringMachine Int -> Int
forall s a. s -> Getting a s a -> a
^.(Quadruples -> Const Int Quadruples)
-> TuringMachine -> Const Int TuringMachine
Lens' TuringMachine Quadruples
quadruples((Quadruples -> Const Int Quadruples)
 -> TuringMachine -> Const Int TuringMachine)
-> ((Int -> Const Int Int) -> Quadruples -> Const Int Quadruples)
-> Getting Int TuringMachine Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Quadruples -> Int)
-> (Int -> Const Int Int) -> Quadruples -> Const Int Quadruples
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to(Quadruples -> Int
forall c. Sizable c => c -> Int
size))
      ]
    showListTitle :: [TuringMachine] -> Title
showListTitle = Title -> [TuringMachine] -> Title
forall a b. a -> b -> a
const Title
"List of Turing Machines"

instance ShowInfo TM where
    showTitle :: TM -> Title
showTitle = Title -> TM -> Title
forall a b. a -> b -> a
const Title
"Turing Machine"
    showInfo :: TM -> String
showInfo (TM (InputAlphabet Set Square
ia, [TapeAlphabet]
tas, MultiTapeStates [Set State]
mts, Commands Set [TapeCommand]
cs, StartStates
_, AccessStates
_)) =
        let stas :: [Int]
stas = [ Set Square -> Int
forall c. Sizable c => c -> Int
size Set Square
ta | TapeAlphabet Set Square
ta <- [TapeAlphabet]
tas ]
            smts :: [Int]
smts = [ Set State -> Int
forall c. Sizable c => c -> Int
size Set State
mt | Set State
mt <- [Set State]
mts ]
        in  ShowS -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n") [
                String
"input alphabet: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Set Square -> Int
forall c. Sizable c => c -> Int
size Set Square
ia),
                String
"tape alphabet: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ([Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [Int]
stas) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Int] -> String
forall a. Show a => a -> String
show [Int]
stas,
                String
"states: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ([Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [Int]
smts) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Int] -> String
forall a. Show a => a -> String
show [Int]
smts,
                String
"commands: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Set [TapeCommand] -> Int
forall c. Sizable c => c -> Int
size Set [TapeCommand]
cs)
              ]
    showListTitle :: [TM] -> Title
showListTitle = Title -> [TM] -> Title
forall a b. a -> b -> a
const Title
"List of Turing Machines"

instance ShowInfo SemigroupPresentation where
    showTitle :: SemigroupPresentation -> Title
showTitle = Title -> SemigroupPresentation -> Title
forall a b. a -> b -> a
const Title
"Semigroup Presentation"
    showInfo :: SemigroupPresentation -> String
showInfo SemigroupPresentation
sp = ShowS -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n") [
        String
"generators: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (SemigroupPresentation
spSemigroupPresentation
-> Getting Int SemigroupPresentation Int -> Int
forall s a. s -> Getting a s a -> a
^.(Set Generator -> Const Int (Set Generator))
-> SemigroupPresentation -> Const Int SemigroupPresentation
SPGetter (Set Generator)
SP.allGenerators((Set Generator -> Const Int (Set Generator))
 -> SemigroupPresentation -> Const Int SemigroupPresentation)
-> ((Int -> Const Int Int)
    -> Set Generator -> Const Int (Set Generator))
-> Getting Int SemigroupPresentation Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Set Generator -> Int)
-> (Int -> Const Int Int)
-> Set Generator
-> Const Int (Set Generator)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to(Set Generator -> Int
forall c. Sizable c => c -> Int
size)),
        String
"relations: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (SemigroupPresentation
spSemigroupPresentation
-> Getting Int SemigroupPresentation Int -> Int
forall s a. s -> Getting a s a -> a
^.(Relations -> Const Int Relations)
-> SemigroupPresentation -> Const Int SemigroupPresentation
Lens' SemigroupPresentation Relations
SP.relations((Relations -> Const Int Relations)
 -> SemigroupPresentation -> Const Int SemigroupPresentation)
-> ((Int -> Const Int Int) -> Relations -> Const Int Relations)
-> Getting Int SemigroupPresentation Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Relations -> Int)
-> (Int -> Const Int Int) -> Relations -> Const Int Relations
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to(Relations -> Int
forall c. Sizable c => c -> Int
size))
      ]
    showListTitle :: [SemigroupPresentation] -> Title
showListTitle = Title -> [SemigroupPresentation] -> Title
forall a b. a -> b -> a
const Title
"List of Semigroup Presentations"

instance ShowInfo GroupPresentation where
    showTitle :: GroupPresentation -> Title
showTitle = Title -> GroupPresentation -> Title
forall a b. a -> b -> a
const Title
"Group Presentation"
    showInfo :: GroupPresentation -> String
showInfo GroupPresentation
gp = ShowS -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n") [
        String
"generators: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (GroupPresentation
gpGroupPresentation -> Getting Int GroupPresentation Int -> Int
forall s a. s -> Getting a s a -> a
^.(Set Generator -> Const Int (Set Generator))
-> GroupPresentation -> Const Int GroupPresentation
GPGetter (Set Generator)
GP.allGenerators((Set Generator -> Const Int (Set Generator))
 -> GroupPresentation -> Const Int GroupPresentation)
-> ((Int -> Const Int Int)
    -> Set Generator -> Const Int (Set Generator))
-> Getting Int GroupPresentation Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Set Generator -> Int)
-> (Int -> Const Int Int)
-> Set Generator
-> Const Int (Set Generator)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to(Set Generator -> Int
forall c. Sizable c => c -> Int
size)),
        String
"relations: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (GroupPresentation
gpGroupPresentation -> Getting Int GroupPresentation Int -> Int
forall s a. s -> Getting a s a -> a
^.(Relations -> Const Int Relations)
-> GroupPresentation -> Const Int GroupPresentation
Lens' GroupPresentation Relations
GP.relations((Relations -> Const Int Relations)
 -> GroupPresentation -> Const Int GroupPresentation)
-> ((Int -> Const Int Int) -> Relations -> Const Int Relations)
-> Getting Int GroupPresentation Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Relations -> Int)
-> (Int -> Const Int Int) -> Relations -> Const Int Relations
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to(Relations -> Int
forall c. Sizable c => c -> Int
size))
      ]
    showListTitle :: [GroupPresentation] -> Title
showListTitle = Title -> [GroupPresentation] -> Title
forall a b. a -> b -> a
const Title
"List of Group Presentations"

instance ShowInfo GR where
    showTitle :: GR -> Title
showTitle = Title -> GR -> Title
forall a b. a -> b -> a
const Title
"Group Presentation"
    showInfo :: GR -> String
showInfo (GR (Set A
a, Set GrRelation
r)) = ShowS -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n") [
        String
"generators: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Set A -> Int
forall c. Sizable c => c -> Int
size Set A
a),
        String
"relations: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Set GrRelation -> Int
forall c. Sizable c => c -> Int
size Set GrRelation
r)
      ]
    showListTitle :: [GR] -> Title
showListTitle = Title -> [GR] -> Title
forall a b. a -> b -> a
const Title
"List of Group Presentations"

instance ShowInfo a => ShowInfo (WithTitle a) where
    showTitle :: WithTitle a -> Title
showTitle (WT (Title
t, a
_)) = Title
t
    showInfo :: WithTitle a -> String
showInfo (WT (Title
t, a
a)) = Title -> ShowS
addTitleWithNewLine Title
t ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. ShowInfo a => a -> String
showInfo a
a
    showTitleAndInfo :: WithTitle a -> String
showTitleAndInfo = WithTitle a -> String
forall a. ShowInfo a => a -> String
showInfo

instance ShowInfo a => ShowInfo [a] where
    showTitle :: [a] -> Title
showTitle = [a] -> Title
forall a. ShowInfo a => [a] -> Title
showListTitle
    showInfo :: [a] -> String
showInfo = [a] -> String
forall a. ShowInfo a => [a] -> String
showListInfo

instance (ShowInfo a, ShowInfo b) => ShowInfo (a, b) where
    showTitle :: (a, b) -> Title
showTitle = Title -> (a, b) -> Title
forall a b. a -> b -> a
const Title
"Pair"
    showInfo :: (a, b) -> String
showInfo (a
a, b
b) = a -> String
forall a. ShowInfo a => a -> String
showTitleAndInfo a
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ b -> String
forall a. ShowInfo a => a -> String
showTitleAndInfo b
b
    showListTitle :: [(a, b)] -> Title
showListTitle = Title -> [(a, b)] -> Title
forall a b. a -> b -> a
const Title
"List of Pairs"

instance (ShowInfo a, ShowInfo b, ShowInfo c) => ShowInfo (a, b, c) where
    showTitle :: (a, b, c) -> Title
showTitle = Title -> (a, b, c) -> Title
forall a b. a -> b -> a
const Title
"Triple"
    showInfo :: (a, b, c) -> String
showInfo (a
a, b
b, c
c) =
        a -> String
forall a. ShowInfo a => a -> String
showTitleAndInfo a
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ b -> String
forall a. ShowInfo a => a -> String
showTitleAndInfo b
b String -> ShowS
forall a. [a] -> [a] -> [a]
++ c -> String
forall a. ShowInfo a => a -> String
showTitleAndInfo c
c
    showListTitle :: [(a, b, c)] -> Title
showListTitle = Title -> [(a, b, c)] -> Title
forall a b. a -> b -> a
const Title
"List of Triples"

instance (ShowInfo a, ShowInfo b, ShowInfo c, ShowInfo d) =>
        ShowInfo (a, b, c, d) where
    showTitle :: (a, b, c, d) -> Title
showTitle = Title -> (a, b, c, d) -> Title
forall a b. a -> b -> a
const Title
"Quadruple"
    showInfo :: (a, b, c, d) -> String
showInfo (a
a, b
b, c
c, d
d) =
        a -> String
forall a. ShowInfo a => a -> String
showTitleAndInfo a
a String -> ShowS
forall a. [a] -> [a] -> [a]
++
        b -> String
forall a. ShowInfo a => a -> String
showTitleAndInfo b
b String -> ShowS
forall a. [a] -> [a] -> [a]
++
        c -> String
forall a. ShowInfo a => a -> String
showTitleAndInfo c
c String -> ShowS
forall a. [a] -> [a] -> [a]
++
        d -> String
forall a. ShowInfo a => a -> String
showTitleAndInfo d
d
    showListTitle :: [(a, b, c, d)] -> Title
showListTitle = Title -> [(a, b, c, d)] -> Title
forall a b. a -> b -> a
const Title
"List of Quadruples"