Coder Social home page Coder Social 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 }"
  ...

hs-portray's People

Contributors

awpr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

awpr isabella232

hs-portray's Issues

Create orphan instance packages for everything reasonably popular.

A pretty-printing ecosystem is only as useful as its collection of instances, and right now nothing outside of base, containers, and my own libraries has instances. The best I can do without convincing maintainers to buy into the idea is to provide orphans in appropriately-scoped packages.

Proposed setup

  • portray is still just the types, class, and instances for GHC-bundled libraries.
  • Several packages like portray-unordered-containers-orphans provide orphans for packages or small sets of related packages.
  • A portray-batteries package provides Data.Portray.Batteries with (all or a curated selection of) orphan instances and re-exports of some stuff (possibly even the prettyprinter integration).

This way, we get three main upsides:

  • portray is still a tiny dependency, so it's palatable for maintainers to provide instances.
  • It becomes convenient to adopt the library in an application codebase: just depend on portray-batteries.
  • Dependency-conscious application codebases can still benefit: depend on portray and whichever orphan packages you want.

[Docs] Possible outdated documentation

We have identified 1 possible instance of outdated documentation:

About

This is part of a research project that aims to automatically detect outdated documentation in GitHub repositories. We are evaluating the validity of our approach by identifying instances of outdated documentation in real-world projects.

We hope that this research will be a step towards keeping documentation up-to-date. If this has been helpful, consider updating the documentation to keep it in sync with the source code. If this has not been helpful, consider updating this issue with an explanation, so that we can improve our approach. Thanks!

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.