portray-prettyprinter 0.2.0 → 0.2.1
raw patch · 4 files changed
+355/−87 lines, 4 filesdep ~basedep ~portraydep ~prettyprinterPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, portray, prettyprinter, prettyprinter-ansi-terminal, text
API changes (from Hackage documentation)
+ Data.Portray.Prettyprinter: prettyConfig :: Config
+ Data.Portray.Prettyprinter: prettyShowPortrayalLazy :: Portrayal -> Text
+ Data.Portray.Prettyprinter: setScientificNotationThreshold :: Int -> Config -> Config
+ Data.Portray.Prettyprinter: setSeparatorGroupSizes :: (Base -> [Int]) -> Config -> Config
+ Data.Portray.Prettyprinter: setTrimTrailingFloatZeros :: Bool -> Config -> Config
+ Data.Portray.Prettyprinter: styleShowPortrayalLazy :: Config -> (SyntaxClass -> Maybe AnsiStyle) -> Portrayal -> Text
Files
- CHANGELOG.md +12/−4
- portray-prettyprinter.cabal +28/−36
- src/Data/Portray/Prettyprinter.hs +197/−27
- test/Main.hs +118/−20
CHANGELOG.md view
@@ -1,11 +1,19 @@-# 0.1.0+# 0.2.1 (2022-09-24) -Initial version.+* Update to `portray-0.3.0`.+* Fix an alignment bug in list/tuple elements.+* Support flexible configuration of floating-point literals.+* Support configuration of numeric place separators.+* Use lazy Text internally in `pp` and `ppd` to support large/infinite values. -# 0.2.0+# 0.2.0 (2021-09-17) -* Update to portray-0.2.0.+* Update to `portray-0.2.0`. * Add colorized pretty-printing for `pp` and `ppd`. * Fix records/lists/tuples putting initial elements on their own lines. * Flow string literals onto multiple lines, preferring to break after `\n`s. * Support configurable string escaping, to allow printing Unicode in strings.++# 0.1.0 (2021-09-14)++Initial version.
portray-prettyprinter.cabal view
@@ -1,38 +1,34 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.33.0.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack------ hash: 9a1c9decccd042e10d029755324f91da86d55e74574de17e95f313f00dd9a59b name: portray-prettyprinter-version: 0.2.0-synopsis: A portray backend using the prettyprinter package.+version: 0.2.1+synopsis: Portray backend for prettyprinter description: This provides a <https://hackage.haskell.org/package/prettyprinter prettyprinter> backend for <https://hackage.haskell.org/package/portray portray> along with derivable 'Pretty' instances for types with 'Portray' instances. .- This started out as a fork of- <https://hackage.haskell.org/package/portray-pretty portray-pretty>, and is- still very similar. However, @prettyprinter@ gives more flexibility to- documents at the cost of requiring more behavior to be specified explicitly.- As such, some formats are nicer with the @prettyprinter@ backend,- configurable syntax highlighting is supported, and unicode escaping is- configurable. However, this backend is less mature and hasn't been used as- much in practice, so there are likely more formatting bugs than in- @portray-pretty@. Please do file bugs on the GitHub issue tracker if you- find anything that seems obviously wrong!+ This backend has largely superseded the original+ <https://hackage.haskell.org/package/portray-pretty portray-pretty>. Because+ @prettyprinter@ gives more flexibility to documents at the cost of requiring+ more behavior to be specified explicitly, some formats are nicer with this+ backend, configurable syntax highlighting is supported, and unicode escaping+ is configurable. However, as this backend is still newer, there are+ potentially more unnoticed formatting bugs. Please do file bugs on the+ GitHub issue tracker if you find anything that seems obviously wrong! . Try using 'pp' as the print function in GHCi: @:set -interactive-print=Data.Portray.Prettyprinter.pp@! category: Text-homepage: https://github.com/google/hs-portray#readme-bug-reports: https://github.com/google/hs-portray/issues-author: Andrew Pritchard <awpr@google.com>-maintainer: Andrew Pritchard <awpr@google.com>-copyright: 2021 Google LLC+homepage: https://github.com/awpr/portray#readme+bug-reports: https://github.com/awpr/portray/issues+author: Andrew Pritchard <awpritchard@gmail.com>+maintainer: Andrew Pritchard <awpritchard@gmail.com>+copyright: 2021 Google LLC; 2022 Andrew Pritchard license: Apache-2.0 license-file: LICENSE build-type: Simple@@ -41,43 +37,39 @@ source-repository head type: git- location: https://github.com/google/hs-portray+ location: https://github.com/awpr/portray subdir: portray-prettyprinter library exposed-modules: Data.Portray.Prettyprinter- other-modules:- Paths_portray_prettyprinter hs-source-dirs: src build-depends:- base >=4.12 && <4.16- , portray >=0.2 && <0.3- , portray-diff >=0.1 && <0.2- , prettyprinter >=1.7 && <1.8- , prettyprinter-ansi-terminal >=1.1.2 && <1.2- , text >=0.1 && <1.3+ base >=4.12 && <4.17+ , portray ==0.3.*+ , portray-diff ==0.1.*+ , prettyprinter >=1.2 && <1.8+ , prettyprinter-ansi-terminal >=1.1.1 && <1.2+ , text >=0.1 && <2.1 default-language: Haskell2010 test-suite PortrayPrettyprinter-test type: exitcode-stdio-1.0 main-is: Main.hs- other-modules:- Paths_portray_prettyprinter hs-source-dirs: test build-depends: HUnit , QuickCheck- , base >=4.12 && <4.16+ , base >=4.12 && <4.17 , portray- , portray-diff >=0.1 && <0.2+ , portray-diff ==0.1.* , portray-prettyprinter- , prettyprinter >=1.7 && <1.8- , prettyprinter-ansi-terminal >=1.1.2 && <1.2+ , prettyprinter >=1.2 && <1.8+ , prettyprinter-ansi-terminal >=1.1.1 && <1.2 , test-framework , test-framework-hunit , test-framework-quickcheck2- , text >=0.1 && <1.3+ , text >=0.1 && <2.1 default-language: Haskell2010
src/Data/Portray/Prettyprinter.hs view
@@ -1,4 +1,5 @@ -- Copyright 2021 Google LLC+-- Copyright 2022 Andrew Pritchard -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License.@@ -81,6 +82,7 @@ -- This module also exports the underlying rendering functionality in a variety -- of forms for more esoteric uses. +{-# LANGUAGE CPP #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}@@ -96,9 +98,12 @@ , WrappedPortray(..) -- * Rendering -- ** Configuration- , Config, defaultConfig+ , Config, defaultConfig, prettyConfig -- *** Escape Sequences , setShouldEscapeChar, escapeNonASCII, escapeSpecialOnly+ -- *** Numeric Literals+ , setTrimTrailingFloatZeros, setScientificNotationThreshold+ , setSeparatorGroupSizes -- ** Colorization , SyntaxClass(..), LitKind(..) , defaultStyling, subtleStyling, noStyling@@ -106,7 +111,9 @@ , DocAssocPrec, toDocAssocPrecF, toDocAssocPrec -- ** Convenience Functions , portrayalToDoc- , styleShowPortrayal, prettyShowPortrayal, basicShowPortrayal+ , styleShowPortrayal, styleShowPortrayalLazy+ , prettyShowPortrayal, prettyShowPortrayalLazy+ , basicShowPortrayal ) where import Data.Char (isAscii, isDigit, isPrint)@@ -114,18 +121,28 @@ import Data.Functor ((<&>)) import Data.Text (Text) import qualified Data.Text as T-import qualified Data.Text.IO as T (putStrLn)+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.IO as T (putStrLn) import GHC.Show (showLitChar) -import Prettyprinter (Doc, Pretty(..))-import qualified Prettyprinter.Render.Terminal as A -- for ANSI-import qualified Prettyprinter as P+#if MIN_VERSION_prettyprinter(1, 7, 0)+#define Prettyprinter_ Prettyprinter+#else+#define Prettyprinter_ Data.Text.Prettyprint.Doc+#endif +import Prettyprinter_ (Doc, Pretty(..))+import qualified Prettyprinter_.Render.Terminal as A -- for ANSI+import qualified Prettyprinter_ as P+ import Data.Portray ( Assoc(..), Infixity(..), FactorPortrayal(..) , Ident(..), IdentKind(..) , Portray, Portrayal(..), PortrayalF(..) , cata, portray+ , Base(..), FloatLiteral(..)+ , formatIntLit, formatFloatLit, formatSpecialFloat+ , normalizeFloatLit, trimFloatLit ) import Data.Portray.Diff (Diff(..)) @@ -134,7 +151,7 @@ -- This uses ANSI color codes, so take care not to use it in contexts where it -- might output to something other than a terminal. pp :: Portray a => a -> IO ()-pp = T.putStrLn . prettyShowPortrayal . portray+pp = T.putStrLn . prettyShowPortrayalLazy . portray -- | Pretty-print a value using its 'Portray' instance. --@@ -147,7 +164,7 @@ -- This uses ANSI color codes, so take care not to use it in contexts where it -- might output to something other than a terminal. ppd :: Diff a => a -> a -> IO ()-ppd x = T.putStrLn . maybe "_" prettyShowPortrayal . diff x+ppd x = T.putStrLn . maybe "_" prettyShowPortrayalLazy . diff x -- | Pretty-print a diff between two values using a 'Diff' instance. --@@ -244,6 +261,16 @@ -- are always escaped, and anything that wouldn't be escaped by 'Show' is never -- escaped. --+-- * 'setTrimTrailingFloatZeros', whether to trim trailing zeros in+-- floating-point literals.+--+-- * 'setScientificNotationThreshold', a limit on the number of padding+-- (non-precision) zeros in floating-point literals before switching to+-- scientific notation.+--+-- * 'setSeparatorGroupSizes', configuration of where to place underscores in+-- the whole-number part of integral and fractional literals.+-- -- For forwards-compatibility reasons, the field selectors and constructor of -- this type are hidden; use the provided setters to build a config. For -- example:@@ -252,21 +279,120 @@ -- config = -- defaultConfig -- & setShouldEscapeChar (const True) -- Escape everything we can.+-- & setTrimTrailingFloatZeros True -- @ data Config = Config { _shouldEscapeChar :: Char -> Bool+ , _scientificNotationThreshold :: Int+ , _trimTrailingFloatZeros :: Bool+ , _separatorGroupSizes :: Base -> [Int] } -- | Set the predicate for whether to escape a given character; see 'Config'. setShouldEscapeChar :: (Char -> Bool) -> Config -> Config-setShouldEscapeChar f _ = Config f+setShouldEscapeChar f c = c { _shouldEscapeChar = f } --- | A sensible default configuration to build on.+-- | Configure trimming of trailing zeros from floating-point literals. ----- Uses 'escapeNonASCII'.+-- @since 0.2.1+setTrimTrailingFloatZeros :: Bool -> Config -> Config+setTrimTrailingFloatZeros b c = c { _trimTrailingFloatZeros = b }++-- | Configure the number of zeros to pad with before using scientific notation.+--+-- If the radix point is within or adjaecent to the specified digits in a float+-- literal, it's considered to need no padding zeros. If the radix point is+-- outside the specified digits, we can either materialize extra zeros to cover+-- the gap between the specified digits and the radix point, or use scientific+-- notation to move the radix point into the specified digits. A single+-- placeholder zero to the left of the radix point is not considered to be a+-- padding zero.+--+-- @+-- FloatLiteral False "1234" (-4) = _.____1 234+-- = 0.00001 234 -- 4 padding 0s+-- = 1.234e-5+-- @+--+-- @+-- FloatLiteral False "1234" 8 = 1 234____._+-- = 1 2340000 -- 4 padding 0s+-- = 1.234e7+-- @+--+-- Trailing that are part of the specified digits are not considered to be+-- padding (if not trimmed by 'setTrimTrailingFloatZeros'):+--+-- @+-- FloatLiteral False "100" 4 = 1 00_._+-- = 1 000 -- 1 padding 0+-- = 1.000e3+-- @+--+-- This threshold determines how many padding zeros to tolerate before+-- switching over to scientific notation. Choosing a very high threshold+-- naturally means scientific notation will ~never be used. Choosing a+-- negative threshold naturally means scientific notation will always be used.+--+-- Deciding based on the number of padding zeros rather than the absolute+-- magnitude of the number means we won't needlessly format @1234567@ as+-- @1.234567e6@ when doing so doesn't actually make the representation more+-- compact.+--+-- @since 0.2.1+setScientificNotationThreshold :: Int -> Config -> Config+setScientificNotationThreshold n c = c { _scientificNotationThreshold = n }++-- | Set the separator spacing for NumericUnderscores, or disable underscores.+--+-- The list of group sizes is used working leftwards from the radix point. If+-- the list runs out, no further separators will be inserted.+--+-- @+-- [4, 3, 2, 2] : 123456000000 => 1_23_45_600_0000+-- repeat 3 : 123456000000 => 123_456_000_000+-- [1] : 123456000000 => 12345600000_0+-- @+--+-- This allows both the conventional US separator placement of every three+-- digits by providing @cycle 3@, as well as more complex spacings such as+-- @3 : repeat 2@ reportedly used in India.+--+-- Backends should not cache these lists, and should attempt to use them in a+-- single-use, streaming manner, so that large portions of infinite lists are+-- not held in memory. Clients should assume returning infinite lists is fine.+--+-- @since 0.2.1+setSeparatorGroupSizes :: (Base -> [Int]) -> Config -> Config+setSeparatorGroupSizes f c = c { _separatorGroupSizes = f }++-- | A sensible, conservative default configuration to build on.+--+-- * Uses 'escapeNonASCII' to escape everything but printable ASCII characters.+-- * Preserves any trailing zeros in float literals.+-- * Uses scientific notation when any padding zeros would be needed.+-- * Does not use numeric underscores. defaultConfig :: Config-defaultConfig = Config escapeNonASCII+defaultConfig = Config escapeNonASCII 0 False (const []) +-- | A default "pretty" config with more opinionated choices.+--+-- This using numeric underscores, slightly less scientific notation, and less+-- escaping compared to 'defaultConfig'.+--+-- @since 0.2.1+prettyConfig :: Config+prettyConfig =+ defaultConfig+ & setShouldEscapeChar escapeSpecialOnly+ & setScientificNotationThreshold 2+ & setSeparatorGroupSizes+ (\case+ Decimal -> repeat 3 -- Conventional US spacing: powers of 1,000.+ Binary -> repeat 8 -- 8-bit groups.+ Octal -> [] -- /shrug/ doesn't divide bytes evenly.+ Hex -> repeat 8) -- 32-bit groups.+ -- | Convert a 'Portrayal' to a 'Doc'. portrayalToDoc :: Config -> Portrayal -> Doc SyntaxClass portrayalToDoc cfg t = toDocAssocPrec cfg t AssocNope (-1)@@ -330,12 +456,10 @@ [] -> opener <> closer (doc:docs) -> P.group $- foldl01- (\x y -> x <> P.group (P.line' <> y))- id- mempty- (opener <> P.flatAlt " " "" <> doc :- zipWith (P.<+>) (repeat separator) docs) <>+ opener <> P.flatAlt " " "" <> P.align doc <>+ foldMap+ (\x -> P.group (P.line' <> x))+ (map (\x -> separator P.<+> P.align x) docs) <> P.line' <> closer where opener = P.annotate Bracket o@@ -469,6 +593,26 @@ backslashBreak = P.annotate EscapeSequence $ "\\" <> P.line' <> "\\" +ppIntLit :: Base -> [Int] -> Integer -> Doc SyntaxClass+ppIntLit b seps = P.annotate (Literal IntLit) . text . formatIntLit b seps++paddingZeros :: FloatLiteral -> Int+paddingZeros (FloatLiteral _ d e)+ | e < 0 = negate e+ | e > T.length d = e - T.length d+ | otherwise = 0++ppFloatLit :: Config -> FloatLiteral -> Doc SyntaxClass+ppFloatLit cfg lit =+ P.annotate (Literal RatLit) $ text $+ formatFloatLit+ (paddingZeros lit' > _scientificNotationThreshold cfg)+ (_separatorGroupSizes cfg Decimal) lit'+ where+ lit' =+ (if _trimTrailingFloatZeros cfg then trimFloatLit else id) $+ normalizeFloatLit lit+ -- | Render one layer of 'PortrayalF' to 'DocAssocPrec'. toDocAssocPrecF :: Config@@ -476,27 +620,36 @@ -> DocAssocPrec SyntaxClass toDocAssocPrecF cfg = \case NameF nm -> \_ _ -> ppPrefix nm- LitIntF x -> \_ _ -> P.annotate (Literal IntLit) $ pretty x- LitRatF x -> \_ _ ->- P.annotate (Literal RatLit) $ pretty (fromRational x :: Double)+ LitIntBaseF base x -> \_ _ -> ppIntLit base (_separatorGroupSizes cfg base) x+ LitFloatF x -> \_ _ -> ppFloatLit cfg x++ SpecialFloatF x -> \_ _ ->+ P.annotate Structural $ text $ -- Different color from numeric float lits.+ formatSpecialFloat x+ LitStrF x -> \_ _ -> ppStrLit cfg x+ LitCharF x -> \_ _ -> -- Likewise Char P.annotate (Literal CharLit) $ P.enclose "'" "'" $ (if litCharIsEscaped cfg x then P.annotate EscapeSequence else id) $ text $ escapeLitChar cfg x+ OpaqueF txt -> \_ _ -> text txt ApplyF fn [] -> \_ _ -> fn AssocL 10+ ApplyF fn xs -> \lr p -> maybeParens (not $ fixityCompatible (Infixity AssocL 10) lr p) $ P.nest 2 $ P.sep [ fn AssocL 10 , P.sep $ xs <&> \docprec -> docprec AssocR 10 ]+ BinopF nm fx x y -> ppBinop nm fx x y TupleF xs -> \_ _ -> ppBulletList "(" "," ")" $ xs <&> \x -> x AssocNope (-1) ListF xs -> \_ _ -> ppBulletList "[" "," "]" $ xs <&> \x -> x AssocNope (-1)+ LambdaCaseF xs -> \_ p -> maybeParens (p >= 10) $ P.nest 2 $ P.sep@@ -509,28 +662,32 @@ | (pat, val) <- xs ] ]+ RecordF con sels -> \_ _ -> case sels of [] -> con AssocNope (-1) _ -> P.nest 2 $ P.sep [ con AssocNope 10 , ppBulletList "{" "," "}"- [ P.nest 4 $ P.sep+ [ P.nest 2 $ P.sep [ ppPrefix sel P.<+> P.annotate Structural "=" , val AssocNope 0 ] | FactorPortrayal sel val <- sels ] ]+ TyAppF val ty -> \_ _ -> P.nest 2 $ P.sep [ val AssocNope 10 , P.annotate Structural "@" <> ty AssocNope 10 ]+ TySigF val ty -> \_ p -> maybeParens (p >= 0) $ P.nest 2 $ P.sep [ val AssocNope 0 , P.annotate Structural "::" P.<+> ty AssocNope 0 ]+ QuotF nm content -> \_ _ -> P.nest 2 $ P.sep [ P.annotate Structural "[" <>@@ -539,6 +696,7 @@ , content AssocNope (-1) , P.annotate Structural "|]" ]+ UnlinesF ls -> \_ _ -> P.vcat (ls <&> \l -> l AssocNope (-1)) NestF n x -> \_ _ -> P.nest n (x AssocNope (-1)) @@ -553,15 +711,27 @@ -- | Convenience function for rendering a 'Portrayal' to colorized 'Text'. prettyShowPortrayal :: Portrayal -> Text prettyShowPortrayal =- styleShowPortrayal- (defaultConfig & setShouldEscapeChar escapeSpecialOnly)- defaultStyling+ styleShowPortrayal prettyConfig defaultStyling +-- | A lazy 'TL.Text' variant of 'prettyShowPortrayal'.+--+-- @since 0.2.1+prettyShowPortrayalLazy :: Portrayal -> TL.Text+prettyShowPortrayalLazy =+ styleShowPortrayalLazy prettyConfig defaultStyling+ -- | Convenience function for rendering a 'Portrayal' to stylized 'Text'. styleShowPortrayal :: Config -> (SyntaxClass -> Maybe A.AnsiStyle) -> Portrayal -> Text-styleShowPortrayal cfg style p =- A.renderStrict $ P.alterAnnotationsS style $+styleShowPortrayal cfg style = TL.toStrict . styleShowPortrayalLazy cfg style++-- | A lazy 'TL.Text' variant of 'styleShowPortrayal'.+--+-- @since 0.2.1+styleShowPortrayalLazy+ :: Config -> (SyntaxClass -> Maybe A.AnsiStyle) -> Portrayal -> TL.Text+styleShowPortrayalLazy cfg style p =+ A.renderLazy $ P.alterAnnotationsS style $ P.layoutPretty P.defaultLayoutOptions $ toDocAssocPrec cfg p AssocNope (-1)
test/Main.hs view
@@ -1,4 +1,5 @@ -- Copyright 2021 Google LLC+-- Copyright 2022 Andrew Pritchard -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License.@@ -12,6 +13,7 @@ -- See the License for the specific language governing permissions and -- limitations under the License. +{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DerivingVia #-}@@ -21,14 +23,21 @@ module Main where +import Data.Fixed (Fixed, E3) import Data.Function ((&)) import Data.Text (Text) import qualified Data.Text as T import GHC.Read (readLitChar) import GHC.Show (showLitChar) -import qualified Prettyprinter as P-import qualified Prettyprinter.Render.Text as R+#if MIN_VERSION_prettyprinter(1, 7, 0)+#define Prettyprinter_ Prettyprinter+#else+#define Prettyprinter_ Data.Text.Prettyprint.Doc+#endif++import qualified Prettyprinter_ as P+import qualified Prettyprinter_.Render.Text as R import Test.Framework (defaultMain, testGroup) import Test.Framework.Providers.HUnit (testCase) import Test.Framework.Providers.QuickCheck2 (testProperty)@@ -69,13 +78,93 @@ propCharRoundTrips :: Config -> Char -> Property propCharRoundTrips cfg c = c === read (T.unpack $ showPortrayalCfg cfg c) +altShowPortrayal :: Portrayal -> Text+altShowPortrayal =+ styleShowPortrayal+ (prettyConfig & setTrimTrailingFloatZeros True)+ (const mempty)+ main :: IO () main = defaultMain- [ testGroup "Atom"- [ testCase "()" $ basicShowPortrayal (Tuple []) @?= "()"- , testCase "2" $ basicShowPortrayal (LitInt 2) @?= "2"+ [ testGroup "LitInt"+ [ testCase "2" $ basicShowPortrayal (LitInt 2) @?= "2"+ , testCase "1000" $ basicShowPortrayal (LitInt 1000) @?= "1000"++ , testCase "0o123" $+ basicShowPortrayal (LitIntBase Octal 0o123) @?= "0o123"++ , testCase "0b10000000" $+ basicShowPortrayal (LitIntBase Binary 128) @?= "0b10000000"++ , testCase "0xdeadbeef" $+ basicShowPortrayal (LitIntBase Hex 0xdeadbeef) @?=+ "0xdeadbeef"++ , testCase "2_" $ altShowPortrayal (LitInt 2) @?= "2"+ , testCase "1_000" $ altShowPortrayal (LitInt 1000) @?= "1_000"+ , testCase "1_000_000" $ altShowPortrayal (LitInt 1000000) @?= "1_000_000"++ , testCase "0o123456" $+ altShowPortrayal (LitIntBase Octal 0o123456) @?= "0o123456"++ , testCase "0b1_00001000" $+ altShowPortrayal (LitIntBase Binary 0x0108) @?= "0b1_00001000"++ , testCase "0xfeedface_deadbeef" $+ altShowPortrayal (LitIntBase Hex 0xfeedfacedeadbeef) @?=+ "0xfeedface_deadbeef" ] + , testGroup "LitFloat"+ [ testCase "2" $+ basicShowPortrayal (LitFloat (floatToLiteral (2 :: Float))) @?= "2"++ , testCase "1e6" $+ basicShowPortrayal (LitFloat (floatToLiteral (1e6 :: Float))) @?=+ "1e6"++ , testCase "1.02e-4" $+ basicShowPortrayal (LitFloat (floatToLiteral (1.02e-4 :: Float))) @?=+ "1.02e-4"++ , testCase "5/3" $+ basicShowPortrayal (LitFloat (floatToLiteral (5/3 :: Float))) @?=+ "1.6666666"++ , testCase "2.000" $+ basicShowPortrayal (LitFloat (fixedToLiteral (2 :: Fixed E3))) @?=+ "2.000"++ , testCase "2000.000" $+ basicShowPortrayal (LitFloat (fixedToLiteral (2000 :: Fixed E3))) @?=+ "2000.000"++ , testCase "5/3 :: Double" $+ basicShowPortrayal (LitFloat (floatToLiteral (5/3 :: Double))) @?=+ "1.6666666666666667"++ , testCase "5000/3" $+ basicShowPortrayal (LitFloat (floatToLiteral (5000/3 :: Float))) @?=+ "1666.6666"++ , testCase "5_000/3" $+ altShowPortrayal (LitFloat (floatToLiteral (5000/3 :: Float))) @?=+ "1_666.6666"++ , testCase "2 :: Fixed E3" $+ altShowPortrayal (LitFloat (fixedToLiteral (2 :: Fixed E3))) @?= "2"++ , testCase "2e3 :: Fixed E3" $+ altShowPortrayal (LitFloat (fixedToLiteral (2000 :: Fixed E3))) @?=+ "2e3"++ , testCase "NaN" $ basicShowPortrayal (SpecialFloat NaN) @?= "NaN"+ , testCase "Infinity" $+ basicShowPortrayal (SpecialFloat $ Infinity False) @?= "Infinity"+ , testCase "-Infinity" $+ basicShowPortrayal (SpecialFloat $ Infinity True) @?= "-Infinity"+ ]+ , testGroup "Apply" [ testCase "nullary" $ basicShowPortrayal (Apply (Name "Nothing") []) @?= "Nothing"@@ -151,7 +240,8 @@ ] , testGroup "Tuple"- [ testCase "pair" $+ [ testCase "nullary" $ basicShowPortrayal (Tuple []) @?= "()"+ , testCase "pair" $ basicShowPortrayal (Tuple [LitInt 2, LitInt 4]) @?= "(2, 4)" , testCase "triple" $ basicShowPortrayal (Tuple [LitInt 2, LitInt 4, LitInt 6]) @?=@@ -159,9 +249,9 @@ , testCase "line-break" $ basicShowPortrayal (Tuple [strAtom "222", strAtom (replicate 80 '2')]) @?=- "( 222\n\- \, 2222222222222222222222222222222222222222222222222222222222222\- \2222222222222222222\n\+ "( 222\n\\+ \, 2222222222222222222222222222222222222222222222222222222222222\\+ \2222222222222222222\n\\ \)" ] @@ -169,6 +259,14 @@ [ testCase "empty" $ basicShowPortrayal (List []) @?= "[]" , testCase "singleton" $ basicShowPortrayal (List [LitInt 2]) @?= "[2]"+ , testCase "nested" $+ basicShowPortrayal+ (portray [[1..25 :: Int]]) @?=+ "[ [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17\\+ \, 18, 19, 20, 21\n\\+ \ , 22, 23, 24, 25\n\\+ \ ]\n\\+ \]" ] , testGroup "LambdaCase"@@ -187,9 +285,9 @@ [ (Name "True", strAtom (replicate 40 '2')) , (Name "False", strAtom (replicate 40 '4')) ]) @?=- "\\case\n\- \ { True -> 2222222222222222222222222222222222222222\n\- \ ; False -> 4444444444444444444444444444444444444444\n\+ "\\case\n\\+ \ { True -> 2222222222222222222222222222222222222222\n\\+ \ ; False -> 4444444444444444444444444444444444444444\n\\ \ }" , testCase "no-parens" $ basicShowPortrayal@@ -222,9 +320,9 @@ [ FactorPortrayal "l" (portray @[Int] [0..10]) , FactorPortrayal "r" (portray @[Int] [0..10]) ]) @?=- "These\n\- \ { l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\- \ , r = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\+ "These\n\\+ \ { l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\\+ \ , r = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\\ \ }" , testCase "break-equals" $ basicShowPortrayal@@ -233,9 +331,9 @@ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" (Name "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") ]) @?=- "These\n\- \ { aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n\- \ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\+ "These\n\\+ \ { aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n\\+ \ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\\ \ }" ] @@ -252,7 +350,7 @@ (TyApp (strAtom $ replicate 50 'a') (strAtom $ replicate 50 'a')) @?=- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\\ \ @aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ] @@ -270,7 +368,7 @@ (TySig (strAtom $ replicate 50 'a') (strAtom $ replicate 50 'a')) @?=- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\\ \ :: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" , testCase "parens" $ basicShowPortrayal