Git Product home page Git Product logo

hs-portray's Introduction

portray

A compatibility layer between Haskell-like syntax and pretty-printer backends.

Stack CI

Disclaimer

This is not an officially supported Google product.

Hackage Status

  • portray Uploaded Haddock
  • portray-diff Uploaded Haddock
  • portray-pretty Uploaded Haddock
  • portray-prettyprinter Uploaded Haddock
  • portray-diff-hunit Uploaded Haddock
  • portray-diff-quickcheck Uploaded Haddock

Problem Statement

The Haskell ecosystem doesn't have consistently-available pretty-printing functionality for debugging purposes. Many pretty-printers exist providing rendering and typeclasses of pretty-printable types; each has its own advantages and set of devotees, but few libraries on Hackage actually provide instances for any of them. Providing instances for all of the pretty-printers is too onerous and incurs too many dependencies; and no single pretty-printer has sufficient critical mass to convince package maintainers to support it over the others. So, in practice, nothing comes with any pretty-printing support.

In most application codebases of nontrivial size, one of the first things Haskellers end up doing is picking a pretty-printer, writing orphan instances for the whole world, and maintaining instances for their own types alongside the orphans. Doing this from scratch in every new application codebase is a waste of effort. The alternative, even worse, is to throw up one's hands, declare it not worth the effort, and use Show, poring over many-kilobyte-long lines of text.

Bonus Problem

Text.PrettyPrint.HughesPJ.Doc has an NFData instance, but the type relies critically on laziness, and its complete structure grows exponentially with the length of the document, so calling rnf on a document of even relatively modest size has disastrous performance consequences (e.g. inexplicably consume all of your memory and lock up your machine). Laziness-based pretty-printer documents are ill-suited as a data representation; they're primarily a control structure.

Solution

There are 15 competing standards.

No, Really

Create a package providing a type of pseudo-Haskell-syntax terms and a typeclass for values that can be rendered to it; minimize its dependency weight to make it palatable to library maintainers. Provide (in separate packages) renderings of this syntax into various pretty-printer backends. By incurring a small dependency and deriving a single instance, library maintainers can provide support for a wide variety of debugging use cases. Application authors can either use this class as their pretty-printing ecosystem, or use it to derive (rather than hand-code) the orphan instances for any other pretty-printing ecosystem; either way, they save significant effort.

Usage

For Library Maintainers

Depend on portray and optionally wrapped; derive instances for your types with DerivingVia, or hand-write them.

data These a b = This a | That b | These a b
  deriving Generic
  deriving Portray via Wrapped Generic (These a b)

For Application Authors

Depend on portray and a rendering backend, e.g. portray-pretty. From here, you have two main options: either use Portray as the primary carrier of pretty-printing functionality by using showPortrayal and pp, or use Portray to derive instances for your pretty-printing class of choice.

To do the former:

import Data.Portray.Pretty (pp)
...

data MyType = MyType { _mtInt :: Int, _mtBool :: Bool }
  deriving Generic
  deriving Portray via Wrapped Generic MyType

main = do
  ...
  pp (MyType 2 True)
  -- outputs "MyType { _mtInt = 2, _mtBool = True }"
  ...

To do the latter:

import Data.Portray.Pretty (WrappedPortray(..))
import Text.PrettyPrint.HughesPJClass (prettyShow)
...

data MyType = MyType { _mtInt :: Int, _mtBool :: Bool }
  deriving Generic
  deriving Portray via Wrapped Generic MyType
  deriving Pretty via WrappedPortray MyType

main = do
  ...
  putStrLn $ prettyShow (MyType 2 True)
  -- outputs "MyType { _mtInt = 2, _mtBool = True }"
  ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.