1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
--------------------------------------------------------------------------------
--- This library provides a type and combinators for show functions using
--- functional lists.
---
--- @author  Bjoern Peemoeller
--- @version April 2016
--- @category general
--------------------------------------------------------------------------------
module ShowS ( ShowS
             , showString, showChar, showParen, shows
             , space, nl, sep, replicateS, concatS
             ) where

import Test.Prop

type ShowS = String -> String

--- Prepend a string
showString :: String -> ShowS
showString s = (s ++)

showStringIsString s = showString s [] -=- s
showStringConcat s1 s2 = (showString s1 . showString s2) [] -=- s1++s2

--- Prepend a single character
showChar :: Char -> ShowS
showChar c = (c:)

--- Surround the inner show function with parentheses if the first argument
--- evaluates to `True`.
showParen  :: Bool -> ShowS -> ShowS
showParen True  s = showChar '(' . s . showChar ')'
showParen False s = s

--- Convert a value to `ShowS` using the standard show function.
shows :: Show a => a -> ShowS
shows = showString . show

--- Prepend a space
space :: ShowS
space = showChar ' '

--- Prepend a newline
nl :: ShowS
nl = showChar '\n'

--- Separate a list of `ShowS`
sep :: ShowS -> [ShowS] -> ShowS
sep _ []       = id
sep s xs@(_:_) = foldr1 (\ f g -> f . s . g) xs

--- Replicate a `ShowS` a given number of times
replicateS :: Int -> ShowS -> ShowS
replicateS n funcS
  | n <= 0    = id
  | otherwise = funcS . replicateS (n - 1) funcS

replicateSIsConRep n s =
  n>=0 ==> replicateS n (showString s) [] -=- concat (replicate n s)

--- Concatenate a list of `ShowS`
concatS :: [ShowS] -> ShowS
concatS []       = id
concatS xs@(_:_) = foldr1 (\ f g -> f . g) xs

concatSIsConcat xs = concatS (map showString xs) [] -=- concat xs