2

In a ghci session (that happens to be in a jupyter kernel), I'd like to pretty print a list in haskell vertically. (In my use-case, I'm viewing a CSV, so this list represents a column of data, and I'd like the display to reflect that.)

Prelude> print ["1111111111", "2222222222", "3333333333", "4444444444", "5555555555", "6666666666"]
["1111111111","2222222222","3333333333","4444444444","5555555555","6666666666"]

I'm looking at the documentation for GenericPretty:

http://hackage.haskell.org/package/GenericPretty

I have this data:

import Text.PrettyPrint.GenericPretty

Prelude> toprint = ["1111111111", "2222222222", "3333333333", "4444444444", "5555555555", "6666666666"]
Prelude> print toprint -- first, show standard print
["1111111111","2222222222","3333333333","4444444444","5555555555","6666666666"]

Which I am trying to pretty print:

Prelude> pretty toprint
"[\"1111111111\",\"2222222222\",\"3333333333\",\"4444444444\",\n \"5555555555\",\"6666666666\"]"

This is not quite right. You can see it does add one "\n" but it's not after every line and it's interestingly also not acted upon in the interactive session. It's rendered as text rather than printed.

In python, I'd do this:

>>> from pprint import pprint as pp
>>> print(['1111111111', '2222222222', '3333333333', '4444444444', '5555555555', '6666666666'])
['1111111111', '2222222222', '3333333333', '4444444444', '5555555555', '6666666666']
>>> pp(['1111111111', '2222222222', '3333333333', '4444444444', '5555555555', '6666666666'])
['1111111111',
 '2222222222',
 '3333333333',
 '4444444444',
 '5555555555',
 '6666666666']

This vertical tiling separated by "\n" that are printed in my session is exactly what I'm looking for. How do I do this?

Mittenchops
  • 18,633
  • 33
  • 128
  • 246
  • 1
    Is it useful? `putStr . concat . intersperse "\n" . map show $ ["1111111111", "2222222222", "3333333333", "4444444444", "5555555555", "6666666666"]` – assembly.jc Dec 28 '18 at 11:32
  • GHCi printing is defined by the `Show` typeclass. This cannot be redefined without excluding the `Prelude` library. – AJF Dec 28 '18 at 17:29

2 Answers2

4

Iavor Diatchki's pretty-show package does a very good job of this: https://hackage.haskell.org/package/pretty-show

First, install it using cabal install pretty-show. Then:

Prelude> import Text.Show.Pretty
Prelude Text.Show.Pretty> putStrLn  $ ppShow ["1111111111", "2222222222", "3333333333", "4444444444", "5555555555", "6666666666"]
[ "1111111111"
, "2222222222"
, "3333333333"
, "4444444444"
, "5555555555"
, "6666666666"
]

You can even instruct ghci to do this automatically, so you don't have to call ppShow yourself:

Prelude> import Text.Show.Pretty (ppShow, pPrint)
Prelude Text.Show.Pretty> :set -interactive-print pPrint
Prelude Text.Show.Pretty> ["1111111111", "2222222222", "3333333333", "4444444444", "5555555555", "6666666666"]
[ "1111111111"
, "2222222222"
, "3333333333"
, "4444444444"
, "5555555555"
, "6666666666"
]

You can put the relevant instructions in your .ghci file so this happens automagically for you if you like. See this blog post for details: https://teh.id.au/posts/2017/02/13/interactive-print/index.html

alias
  • 28,120
  • 2
  • 23
  • 40
1

One solution to this problem is:

Prelude> mapM_ putStrLn toprint
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666

but I'd be more satisfied using a proper pretty print library where I'd have more flexibility than just newlines for every record.

Mittenchops
  • 18,633
  • 33
  • 128
  • 246