-- | The LineShow type is simply a list type except that it has
-- Read and Show instances which put the output line by line,
-- preceded by the number of lines.  This is useful for data
-- files stored by CVS and similar systems.
module Util.LineShow(
   LineShow(..)
   ) where

newtype LineShow a = LineShow [a]

instance Show a => Show (LineShow a) where
   showsPrec :: Int -> LineShow a -> ShowS
showsPrec Int
prec (LineShow [a]
list) String
acc =
      let
         showLines :: [a] -> ShowS
showLines [] String
acc = String
acc
         showLines (a
h:[a]
t) String
acc = [a] -> ShowS
showLines [a]
t (Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
prec a
h (Char
'\n'Char -> ShowS
forall a. a -> [a] -> [a]
:String
acc))
      in
         (Int -> String
forall a. Show a => a -> String
show ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
list))String -> ShowS
forall a. [a] -> [a] -> [a]
++(Char
'\n'Char -> ShowS
forall a. a -> [a] -> [a]
:[a] -> ShowS
forall a. Show a => [a] -> ShowS
showLines [a]
list String
acc)

instance Read a => Read (LineShow a) where
   readsPrec :: Int -> ReadS (LineShow a)
readsPrec Int
prec String
toRead =
      let
         readLines :: t -> [a] -> String -> [(LineShow a, String)]
readLines t
0 [a]
acc String
toRead = [([a] -> LineShow a
forall a. [a] -> LineShow a
LineShow [a]
acc,String
toRead)]
         readLines t
nLeft [a]
acc String
toRead =
            case Int -> ReadS a
forall a. Read a => Int -> ReadS a
readsPrec Int
prec String
toRead of
               [(a
this,Char
'\n':String
remainder)] ->
                  t -> [a] -> String -> [(LineShow a, String)]
readLines (t
nLeftt -> t -> t
forall a. Num a => a -> a -> a
-t
1) (a
thisa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
acc) String
remainder
               [(a, String)]
_ -> []
      in
         case Int -> ReadS Int
forall a. Read a => Int -> ReadS a
readsPrec Int
prec String
toRead of
            [(Int
nLines,Char
'\n':String
remainder)] -> Int -> [a] -> ReadS (LineShow a)
forall t a.
(Eq t, Num t, Read a) =>
t -> [a] -> String -> [(LineShow a, String)]
readLines (Int
nLines :: Int) [] String
remainder
            [(Int, String)]
_ -> []