haskell / haskell/pretty

Adding emptyLine document

Open
#26 2 comments 1 reaction 0 assignees View on GitHub
Dominant language
Haskell
Stars
75
Forks
32
PR merge metrics
No merged PRs in 30d

Description

Empty lines are useful to separate blocks in printed programs, but unless I'm getting the API wrong, currently only way to produce a empty newline is to use `text ""`. `empty` doesn't work, because it's unit of `$$` and `$+$`.

The problem with `text ""` is that when combined with `nest`, it produces trailing white space. For example, this:

``` haskell
nest 4 (text "" $+$ text "block")
```

Generates this:

```
$
block$
```

I propose implementing an `emptyLine` document, like this:

```
emptyLine :: Doc a
emptyLine = NilAbove Empty
```

This works fine, for example, this program:

``` haskell
print $ nest 4 $ emptyLine $$ text "blah"
print $ nest 4 $ text "blah" $+$ emptyLine
```

prints this:

```
$
blah$
blah$
$
$
```

Which is not bad, but now it's printing an extra new line at the end.

So I think there are two problems:
1. This use of `NilAbove` is actually invalidating some internal invariants. Even though I couldn't manage to produce a broken example with this new doc, in the code it's mentioned that:

```
1) The argument of NilAbove is never Empty. Therefore
a NilAbove occupies at least two lines.
```

Which this change clearly invalidates.
2. We need to make some changes in some of the combinators to handle extra newline printed in the case of `text "blah" $+$ emptyLine`. I think it's printed because of this invalidated invariant.

So at this point I'm hoping to get some comments and ideas. Do you think this is a correct way of doing this? Is there any other way to produce new lines without producing trailing white spaces?

Also, some help with changing internals would be great.

Thanks.

UPDATE: I just tried this program:

``` haskell
print $ nest 4 $ emptyLine $$ (nest 4 $ text "blah")
print $ nest 4 $ (nest 4 $ text "blah") $+$ emptyLine
```

And it produced this:

```
$
blah$
blah$
$
$
```

It's good to see that next line after the `blah` is not indented. Last indented empty line should be fixed when we remove that line.

UPDATE 2: Here's a broken example:

``` haskell
print $ nest 4 $ emptyLine <> (nest 4 $ text "blah")
print $ nest 4 $ (nest 4 $ text "blah") <> emptyLine
```

Output:

```
$
blah$
blah$
$
```

An `emptyLine` should never be indented, that's the whole point of it. Documentation sometimes mention "height" and "width", maybe we should be able to say "emptyLine has height 1 and width 0".

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.