packages feed

pragmatic-show 0.1.2.1 → 0.2.0.0

raw patch · 3 files changed

+175/−41 lines, 3 filesdep ~containersPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: containers

API changes (from Hackage documentation)

- Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show Data.Void.Void
- Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.Event.Internal.Event
- Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.Event.Internal.Lifetime
- Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.IO.Handle.Lock.FileLockingNotSupported
- Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.Integer.Type.Integer
- Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.Natural.Natural
+ Text.Show.Pragmatic: NoPadding :: PaddingMode
+ Text.Show.Pragmatic: PadLeftToAlign :: PaddingMode
+ Text.Show.Pragmatic: PadRightToAlign :: PaddingMode
+ Text.Show.Pragmatic: PadToConstantWidth :: PaddingMode
+ Text.Show.Pragmatic: data PaddingMode
+ Text.Show.Pragmatic: instance Data.Foldable.Foldable t => Data.Foldable.Foldable (Text.Show.Pragmatic.TraverseFirst t b)
+ Text.Show.Pragmatic: instance Data.Foldable.Foldable t => Data.Foldable.Foldable (Text.Show.Pragmatic.TraverseFirstOf3 t b c)
+ Text.Show.Pragmatic: instance Data.Foldable.Foldable t => Data.Foldable.Foldable (Text.Show.Pragmatic.TraverseFirstOf4 t b c d)
+ Text.Show.Pragmatic: instance Data.Foldable.Foldable t => Data.Foldable.Foldable (Text.Show.Pragmatic.TraverseFourth t a b c)
+ Text.Show.Pragmatic: instance Data.Foldable.Foldable t => Data.Foldable.Foldable (Text.Show.Pragmatic.TraverseSecond t a)
+ Text.Show.Pragmatic: instance Data.Foldable.Foldable t => Data.Foldable.Foldable (Text.Show.Pragmatic.TraverseSecondOf3 t a c)
+ Text.Show.Pragmatic: instance Data.Foldable.Foldable t => Data.Foldable.Foldable (Text.Show.Pragmatic.TraverseSecondOf4 t a c d)
+ Text.Show.Pragmatic: instance Data.Foldable.Foldable t => Data.Foldable.Foldable (Text.Show.Pragmatic.TraverseThird t a b)
+ Text.Show.Pragmatic: instance Data.Foldable.Foldable t => Data.Foldable.Foldable (Text.Show.Pragmatic.TraverseThirdOf4 t a b d)
+ Text.Show.Pragmatic: instance Data.Traversable.Traversable t => Data.Traversable.Traversable (Text.Show.Pragmatic.TraverseFirst t b)
+ Text.Show.Pragmatic: instance Data.Traversable.Traversable t => Data.Traversable.Traversable (Text.Show.Pragmatic.TraverseFirstOf3 t b c)
+ Text.Show.Pragmatic: instance Data.Traversable.Traversable t => Data.Traversable.Traversable (Text.Show.Pragmatic.TraverseFirstOf4 t b c d)
+ Text.Show.Pragmatic: instance Data.Traversable.Traversable t => Data.Traversable.Traversable (Text.Show.Pragmatic.TraverseFourth t a b c)
+ Text.Show.Pragmatic: instance Data.Traversable.Traversable t => Data.Traversable.Traversable (Text.Show.Pragmatic.TraverseSecond t a)
+ Text.Show.Pragmatic: instance Data.Traversable.Traversable t => Data.Traversable.Traversable (Text.Show.Pragmatic.TraverseSecondOf3 t a c)
+ Text.Show.Pragmatic: instance Data.Traversable.Traversable t => Data.Traversable.Traversable (Text.Show.Pragmatic.TraverseSecondOf4 t a c d)
+ Text.Show.Pragmatic: instance Data.Traversable.Traversable t => Data.Traversable.Traversable (Text.Show.Pragmatic.TraverseThird t a b)
+ Text.Show.Pragmatic: instance Data.Traversable.Traversable t => Data.Traversable.Traversable (Text.Show.Pragmatic.TraverseThirdOf4 t a b d)
+ Text.Show.Pragmatic: instance GHC.Base.Functor t => GHC.Base.Functor (Text.Show.Pragmatic.TraverseFirst t b)
+ Text.Show.Pragmatic: instance GHC.Base.Functor t => GHC.Base.Functor (Text.Show.Pragmatic.TraverseFirstOf3 t b c)
+ Text.Show.Pragmatic: instance GHC.Base.Functor t => GHC.Base.Functor (Text.Show.Pragmatic.TraverseFirstOf4 t b c d)
+ Text.Show.Pragmatic: instance GHC.Base.Functor t => GHC.Base.Functor (Text.Show.Pragmatic.TraverseFourth t a b c)
+ Text.Show.Pragmatic: instance GHC.Base.Functor t => GHC.Base.Functor (Text.Show.Pragmatic.TraverseSecond t a)
+ Text.Show.Pragmatic: instance GHC.Base.Functor t => GHC.Base.Functor (Text.Show.Pragmatic.TraverseSecondOf3 t a c)
+ Text.Show.Pragmatic: instance GHC.Base.Functor t => GHC.Base.Functor (Text.Show.Pragmatic.TraverseSecondOf4 t a c d)
+ Text.Show.Pragmatic: instance GHC.Base.Functor t => GHC.Base.Functor (Text.Show.Pragmatic.TraverseThird t a b)
+ Text.Show.Pragmatic: instance GHC.Base.Functor t => GHC.Base.Functor (Text.Show.Pragmatic.TraverseThirdOf4 t a b d)
+ Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.Base.Void
+ Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.Event.Internal.Types.Event
+ Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.Event.Internal.Types.Lifetime
+ Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.IO.Handle.Lock.Common.FileLockingNotSupported
+ Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.Num.Integer.Integer
+ Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show GHC.Num.Natural.Natural
+ Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show a => Text.Show.Pragmatic.Show (Data.Functor.Identity.Identity a)
+ Text.Show.Pragmatic: instance Text.Show.Pragmatic.Show a => Text.Show.Pragmatic.Show (GHC.Maybe.Maybe a)
+ Text.Show.Pragmatic: showEach :: (Show a, Traversable t) => PaddingMode -> Int -> t a -> t ShowS
- Text.Show.Pragmatic: showsPrecWithSharedPrecision :: (ShowMagnitudeRangeLimited n, RealFloat sn, Traversable list) => (n -> sn) -> Int -> Int -> list n -> list ShowS
+ Text.Show.Pragmatic: showsPrecWithSharedPrecision :: forall n list sn. (ShowMagnitudeRangeLimited n, RealFloat sn, Traversable list) => (n -> sn) -> Int -> PaddingMode -> Int -> list n -> list ShowS

Files

Text/Show/Pragmatic.hs view
@@ -12,6 +12,12 @@ {-# LANGUAGE FlexibleInstances    #-} {-# LANGUAGE FlexibleContexts     #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE UnicodeSyntax        #-}+{-# LANGUAGE GADTs                #-}+{-# LANGUAGE DeriveFunctor        #-}+{-# LANGUAGE DeriveFoldable       #-}+{-# LANGUAGE DeriveTraversable    #-}  #include "HsBaseConfig.h" @@ -22,6 +28,7 @@        , ltdPrecShowsPrec        , showsPrecWithSharedPrecision        , ShowMagnitudeRangeLimited(..)+       , PaddingMode(..)        ) where  import Prelude hiding (Show(..), shows, print)@@ -161,8 +168,13 @@ import qualified Data.IntMap as ℤMap import qualified Data.Sequence as Seq import qualified Data.Tree as Tree+import Data.Functor.Identity (Identity(..))  +data PaddingMode = NoPadding+                 | PadLeftToAlign+                 | PadRightToAlign+                 | PadToConstantWidth  -- | A drop-in replacement for 'Prelude.Show'. The behaviour is mostly the same: --   the result of 'show' should be valid Haskell code, and 'read'ing back such a@@ -178,20 +190,37 @@ --   it depends on the type and the order of magnitude which amount of rounding is --   appropriate. See <https://github.com/leftaroundabout/pragmatic-show/blob/master/test/tasty/test.hs the test suite> for some examples. class Show a where-  {-# MINIMAL showsPrec | show #-}+  {-# MINIMAL showsPrec | show | showEach #-}   showsPrec :: Int -> a -> ShowS   showsPrec _ x = (show x++)   show :: a -> String   show = (`shows`"")+  showEach :: Traversable t+                => PaddingMode -- ^ Whether / how to ensure that e.g. decimal points line up.+                -> Int         -- ^ Precedence to use for showing each individual element+                -> t a         -- ^ List or other container of elements+                -> t ShowS     -- ^ Every element in the container shown, possibly with+                               --   shared processing like trimmed insignificant decimals+  showEach = defaultShowEach   showList :: [a] -> ShowS   showList = defaultShowList +defaultAssembleListShow :: [ShowS] -> ShowS+defaultAssembleListShow [] = ("[]"++)+defaultAssembleListShow (x:xs) = ('[':) . x . flip (foldr (\y -> (',':) . y)) xs . (']':)+ defaultShowList :: Show a => [a] -> ShowS-defaultShowList [] = ("[]"++)-defaultShowList (x:xs) = ('[':) . shows x . flip (foldr (\y -> (',':) . shows y)) xs . (']':)+defaultShowList = defaultAssembleListShow . showEach NoPadding 0 +defaultShowEach :: (Show a, Traversable t) => PaddingMode -> Int -> t a -> t ShowS+defaultShowEach PadToConstantWidth p l+          = fmap (\r c -> r <> replicate (totalWidth - length r) ' ' <> c) shown+ where totalWidth = maximum $ length<$>shown+       shown = fmap (($ "") . showsPrec p) l+defaultShowEach _ p l = fmap (showsPrec p) l+ shows :: Show a => a -> ShowS-shows = showsPrec 0+shows = runIdentity . showEach NoPadding 0 . Identity  #define StdShow(A)             \ instance Show (A) where {       \@@ -487,66 +516,97 @@   class Show a => ShowMagnitudeRangeLimited a where-  showsPrecMagnitudeRangeLimited :: Int -> Int -> a -> ShowS+  showsPrecMagnitudeRangeLimited+          :: Int     -- ^ Precision of the data type+          -> Int     -- ^ Precedence of the showing context+          -> a       -- ^ Numerical value to show+          -> ShowS  instance Show Float where   showsPrec = ltdPrecShowsPrec 7-  showList = ltdPrecShowList id 7+  showEach = showsPrecWithSharedPrecision id 7 instance ShowMagnitudeRangeLimited Float where   showsPrecMagnitudeRangeLimited = ltdPrecShowsPrec  instance Show Double where   showsPrec = ltdPrecShowsPrec 10-  showList = ltdPrecShowList id 10+  showEach = showsPrecWithSharedPrecision id 10 instance ShowMagnitudeRangeLimited Double where   showsPrecMagnitudeRangeLimited = ltdPrecShowsPrec  instance Show CFloat where   showsPrec = ltdPrecShowsPrec 5-  showList = ltdPrecShowList id 5+  showEach = showsPrecWithSharedPrecision id 5 instance ShowMagnitudeRangeLimited CFloat where   showsPrecMagnitudeRangeLimited = ltdPrecShowsPrec  instance Show CDouble where   showsPrec = ltdPrecShowsPrec 10-  showList = ltdPrecShowList id 10+  showEach = showsPrecWithSharedPrecision id 10 instance ShowMagnitudeRangeLimited CDouble where   showsPrecMagnitudeRangeLimited = ltdPrecShowsPrec -ltdPrecShowList :: (ShowMagnitudeRangeLimited n, RealFloat sn)-                   => (n -> sn) -> Int -> [n] -> ShowS-ltdPrecShowList realise precision vals-          = ('[':) . flip (foldr id)-                          (intersperse (',':)-                             $ showsPrecWithSharedPrecision realise precision 0 vals)-                   . (']':)--showsPrecWithSharedPrecision :: (ShowMagnitudeRangeLimited n, RealFloat sn, Traversable list)+showsPrecWithSharedPrecision :: ∀ n list sn . (ShowMagnitudeRangeLimited n, RealFloat sn, Traversable list)               => (n -> sn)   -- ^ Magnitude-function. Should be a norm.               -> Int         -- ^ Precision of the type, in significant decimals. This will                              --   be used to trim the length of all entries to match the                              --   expected numerical uncertainty of the biggest one.+              -> PaddingMode -- ^ What to do to align decimal points               -> Int         -- ^ Precedence of the enclosing context in which the values                              --   are to be shown.               -> list n      -- ^ Values to show               -> list ShowS  -- ^ Individual values' string representation.-showsPrecWithSharedPrecision realise precision p vals-     = fmap (\val ->-              let uMagn = usableMagnitude $ realise val-              in showsPrecMagnitudeRangeLimited-                   (max 0 $ precision - floor (maxUMag - uMagn)) p val+showsPrecWithSharedPrecision magnitudeFn precision padMode p vals+        = (case padMode of+            PadToConstantWidth -> \strn -> +                  let lenStrn = length strn+                  in (replicate (longestPaddedValLength - lenStrn) ' '++) . (strn++)+            _ -> (++)+           ) <$> paddedShownVals+ where shownVals :: list (n, String)+       shownVals = fmap (\val ->+              let uMagn = usableMagnitude $ magnitudeFn val+              in (val, showsPrecMagnitudeRangeLimited+                   (max 0 $ precision - floor (maxUMag - uMagn)) p val "")             ) vals- where usableMagnitude n+       usableMagnitude n         | n<0            = usableMagnitude (-n)         | n==n, 2*n>n    = logBase 10 n-        | otherwise      = -1/0-       maxUMag = maximum $ usableMagnitude . realise <$> vals+        | otherwise      = -1/0    -- NaN or infinite values are disregarded+       maxUMag = maximum $ usableMagnitude . magnitudeFn <$> vals+       leftmostCharacterMagnitude :: (n, String) -> Int+       leftmostCharacterMagnitude (_, "0") = 0+       leftmostCharacterMagnitude (n, ('-':strn))+                     = 1 + leftmostCharacterMagnitude (n, dropWhile (=='-') strn)+       leftmostCharacterMagnitude (n, '.':strn)+                     = leftmostCharacterMagnitude (n, strn)+       leftmostCharacterMagnitude (n, '0':strn)+                     = 1 + leftmostCharacterMagnitude (n, strn)+       leftmostCharacterMagnitude (n, strn) = floor (usableMagnitude $ magnitudeFn n)+       leftmostColumnMagnitude, rightmostColumnMagnitude :: Int+       leftmostColumnMagnitude = maximum $ leftmostCharacterMagnitude <$> shownVals+       rightmostColumnMagnitude = leftmostColumnMagnitude - maximum (length . snd <$> shownVals)+       administerPadding :: (n, String) -> String+       administerPadding (n,strn) = case padMode of+          NoPadding -> strn+          PadLeftToAlign -> replicate (leftmostColumnMagnitude - lchm) ' ' ++ strn+          _ -> strn ++ replicate (rchm - rightmostColumnMagnitude) ' '+        where lchm, rchm :: Int+              lchm = leftmostCharacterMagnitude (n, strn)+              rchm = lchm - length strn+       paddedShownVals :: list String+       paddedShownVals = administerPadding <$> shownVals+       longestPaddedValLength = maximum $ length <$>paddedShownVals  -- | @'ltdPrecShowsPrec' prcn@ displays floating-point values with a precision --   of at least @prcn@ digits. That does not mean it will necessarily display --   that many digits, rather it tries to always choose the shortest representation --   with the required precision.-ltdPrecShowsPrec :: (RealFloat n) => Int -> Int -> n -> ShowS+ltdPrecShowsPrec :: (RealFloat n)+          => Int     -- ^ Precision of the data type+          -> Int     -- ^ Precedence of the showing context+          -> n       -- ^ Numerical value to show+          -> ShowS ltdPrecShowsPrec precision p n cont     = minimumBy (comparing length)         [ postProc $ ltdPrecShowsPrecDecimal precision p' (preProc n) ""@@ -581,7 +641,7 @@                       $ ('-':) . ltdPrecShowsPrecDecimal precision 0 (negate n)     | n==n*2      = ("Infinity"++)     | e₁₀<7 && lrDigs <= e₁₀-                  = (rDigits++) . (replicate (e₁₀-lrDigs) '0' ++)+                  = shows (round n :: Int)     | e₁₀>0 && e₁₀<3                   = (take e₁₀ rDigits++) . ('.':) . (drop e₁₀ rDigits++)     | e₁₀> -2 && e₁₀<=0@@ -599,6 +659,13 @@          rDigits = reverse rDigits'          lrDigs = length rDigits +instance (Show a) => Show (Identity a) where+  showsPrec p (Identity x) = showParen (p>9) $ ("Identity "++) . showsPrec 11 x++instance (Show a) => Show (Maybe a) where+  showsPrec _ Nothing = ("Nothing"++)+  showsPrec p (Just x) = showParen (p>9) $ ("Just "++) . showsPrec 11 x+ instance (Show a) => Show [a] where   showsPrec _ = showList @@ -616,14 +683,62 @@   showsPrec p (Tree.Node a st) = showParen (p>9)                 $ ("Node "++) . showsPrec 11 a . (' ':) . shows st +data TraverseFirst t b a where+  TraverseFirst :: { firstTraversed :: t (a,b) } -> TraverseFirst t b a+ deriving (Functor, Foldable, Traversable)++data TraverseSecond t a b where+  TraverseSecond :: { secondTraversed :: t (a,b) } -> TraverseSecond t a b+ deriving (Functor, Foldable, Traversable)+ instance (Show a, Show b) => Show (a,b) where-  showsPrec _ (a,b) = ('(':) . shows a . (',':) . shows b . (')':)+  showEach padMode _+         = fmap (\(sa,sb) -> ('(':) . sa . (',':) . sb . (')':))+             .  firstTraversed . showEach padMode 0 . TraverseFirst+             . secondTraversed . showEach padMode 0 . TraverseSecond++data TraverseFirstOf3 t b c a where+  TraverseFirstOf3 :: { firstOf3Traversed :: t (a,b,c) } -> TraverseFirstOf3 t b c a+ deriving (Functor, Foldable, Traversable)++data TraverseSecondOf3 t a c b where+  TraverseSecondOf3 :: { secondOf3Traversed :: t (a,b,c) } -> TraverseSecondOf3 t a c b+ deriving (Functor, Foldable, Traversable)++data TraverseThird t a b c where+  TraverseThird :: { thirdTraversed :: t (a,b,c) } -> TraverseThird t a b c+ deriving (Functor, Foldable, Traversable)+ instance (Show a, Show b, Show c) => Show (a,b,c) where-  showsPrec _ (a,b,c) = ('(':) . shows a . (',':) . shows b . (',':) . shows c . (')':)+  showEach padMode _+       = fmap (\(sa,sb,sc) -> ('(':) . sa . (',':) . sb . (',':) . sc . (')':))+             .  firstOf3Traversed . showEach padMode 0 . TraverseFirstOf3+             . secondOf3Traversed . showEach padMode 0 . TraverseSecondOf3+             .     thirdTraversed . showEach padMode 0 . TraverseThird++data TraverseFirstOf4 t b c d a where+  TraverseFirstOf4 :: { firstOf4Traversed :: t (a,b,c,d) } -> TraverseFirstOf4 t b c d a+ deriving (Functor, Foldable, Traversable)++data TraverseSecondOf4 t a c d b where+  TraverseSecondOf4 :: { secondOf4Traversed :: t (a,b,c,d) } -> TraverseSecondOf4 t a c d b+ deriving (Functor, Foldable, Traversable)++data TraverseThirdOf4 t a b d c where+  TraverseThirdOf4 :: { thirdOf4Traversed :: t (a,b,c,d) } -> TraverseThirdOf4 t a b d c+ deriving (Functor, Foldable, Traversable)++data TraverseFourth t a b c d where+  TraverseFourth :: { fourthTraversed :: t (a,b,c,d) } -> TraverseFourth t a b c d+ deriving (Functor, Foldable, Traversable)+ instance (Show a, Show b, Show c, Show d) => Show (a,b,c,d) where-  showsPrec _ (a,b,c,d) = ('(':)-           . shows a . (',':) . shows b . (',':) . shows c . (',':) . shows d-                        . (')':)+  showEach padMode _+       = fmap (\(sa,sb,sc,sd) -> ('(':).sa.(',':).sb.(',':).sc.(',':).sd.(')':))+             .  firstOf4Traversed . showEach padMode 0 . TraverseFirstOf4+             . secondOf4Traversed . showEach padMode 0 . TraverseSecondOf4+             .  thirdOf4Traversed . showEach padMode 0 . TraverseThirdOf4+             .    fourthTraversed . showEach padMode 0 . TraverseFourth  instance (Integral i, Show i) => Show (Ratio i) where   showsPrec p n@@ -634,10 +749,10 @@  instance Show (Complex Double) where   showsPrec = ltdPrecShowsPrecComplex 10-  showList = ltdPrecShowList magnitude 10+  showEach = showsPrecWithSharedPrecision magnitude 10 instance Show (Complex Float) where   showsPrec = ltdPrecShowsPrecComplex 7-  showList = ltdPrecShowList magnitude 7+  showEach = showsPrecWithSharedPrecision magnitude 7 instance (RealFloat a, Show (Complex a), ShowMagnitudeRangeLimited a)     => ShowMagnitudeRangeLimited (Complex a) where   showsPrecMagnitudeRangeLimited = ltdPrecShowsPrecComplex@@ -648,7 +763,7 @@  | abs r > abs i * 10^precision     = ltdPrecShowsPrec precision p r  | otherwise-    = case ($"")<$>showsPrecWithSharedPrecision id precision 6 [r,i] of+    = case ($ "")<$>showsPrecWithSharedPrecision id precision NoPadding 6 [r,i] of            [sr,"0"] -> showParen (p>7) $ (sr++)            [sr,si] -> showParen (p>6) $ (sr++) . (":+"++) . (si++) 
pragmatic-show.cabal view
@@ -2,18 +2,21 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                pragmatic-show-version:             0.1.2.1+version:             0.2.0.0 synopsis:            Alternative Show class that gives shorter view if possible. description:         The standard 'Show' class is handy for quickly viewing any Haskell                      values without having to think about formatting. However, it often                      produces needlessly clunky string representations, which are difficult                      to parse by eye. This package offers a drop-in replacement which-                     attempts to keep the representation as short as possible.+                     attempts to keep the representation as readable as possible.+                     It does this through more graphical layout, omission of redundant+                     information, and (still quite conservative) trimming of low-significance+                     digits. license:             GPL-3 license-file:        LICENSE author:              Justus Sagemüller homepage:            https://github.com/leftaroundabout/pragmatic-show-maintainer:          (@) jsag $ hvl.no+maintainer:          (@) jsag $ kth.se -- copyright:            category:            Text build-type:          Simple@@ -25,11 +28,11 @@   -- other-modules:          other-extensions:    FlexibleInstances   build-depends:       base >=4.8 && <5-                       , containers >=0.5 && <0.7+                       , containers >=0.5 && <0.9   -- hs-source-dirs:         default-language:    Haskell2010 -test-suite test+test-suite pragmatic-show-test   default-language:     Haskell2010   type:
test/tasty/test.hs view
@@ -39,6 +39,9 @@    , testProperty "(Int,Integer)" $ readBackEq ([]::[(Int,Integer)])    , testProperty "(Int,Integer,(Char,[Int]),String)"          $ readBackEq ([]::[(Int,Integer,(Char,[Int]),String)])+   , testProperty "[(Int,Bool)]" $ readBackEq ([]::[ [(Int,Bool)] ])+   , testProperty "([(Char,Int,Char)],[(Int,Char,Int,Char)])"+         $ readBackEq ([]::[ ([(Char,Int,Char)],[(Int,Char,Int,Char)]) ])    ]   , testGroup "Showing double-precision floats"    [ floatTest 1 "1"@@ -68,6 +71,8 @@    , floatsTest (take 10 $ iterate (/16) 1)        "[1,0.0625,3.90625e-3,2.44140625e-4,1.5258789e-5,9.53674e-7,5.9605e-8,3.725e-9,2.33e-10,1.5e-11]"    , floatsTest [1, -sqrt 2, sqrt (-2)] "[1,-sqrt 2,NaN]"+   , floatsTest [pi**k | k <- [1, 4 .. 30]]+       "[pi,97,3020,93648,2.904e6,9.0032e7,2.791564e9,8.6556004e10,2.683779414e12,8.3214007069e13,2.58015652686e15]"    ]   , testGroup "Showing rational numbers"    [ rationalTest 0 "0"@@ -84,6 +89,11 @@    , complexTest (exp $ 0:+pi/4) "sqrt 2/2:+sqrt 2/2"    , complexTest (exp $ 0:+5*pi/4) "(-sqrt 2/2):+(-sqrt 2/2)"    ]+  , testGroup "Showing tuples and lists of tuples"+   [ floatTupleTest (1.001e-3, 1e40) "(1.001e-3,1e40)"+   , floatTuplesTest [ (1.001e-3,1e40),(3e-3,1.001) ]+                     "[(1.001e-3,1e40),(3e-3,1)]"+   ]   ]  -- | Check that showing and reading again yields the original value.@@ -110,6 +120,12 @@  floatsTest :: [Double] -> String -> TestTree floatsTest n s = testCase s $ show n @?= s++floatTupleTest :: (Double,Double) -> String -> TestTree+floatTupleTest n s = testCase s $ show n @?= s++floatTuplesTest :: [(Double,Double)] -> String -> TestTree+floatTuplesTest n s = testCase s $ show n @?= s  rationalTest :: Rational -> String -> TestTree rationalTest n s = testCase s $ show n @?= s