|
|
# Nondecreasing Indentation
|
|
|
|
|
|
**Ticket:**[\#53](https://gitlab.haskell.org//haskell/prime/issues/53)
|
|
|
|
|
|
## Compiler support
|
|
|
|
|
|
<table><tr><th> GHC </th>
|
|
|
<th> full (-XNondecreasingIndentation; enabled by default)
|
|
|
</th></tr>
|
|
|
<tr><th> nhc98 </th>
|
|
|
<th> unknown
|
|
|
</th></tr>
|
|
|
<tr><th> Hugs </th>
|
|
|
<th> unknown
|
|
|
</th></tr>
|
|
|
<tr><th> UHC </th>
|
|
|
<th> unknown
|
|
|
</th></tr>
|
|
|
<tr><th> JHC </th>
|
|
|
<th> unknown
|
|
|
</th></tr>
|
|
|
<tr><th> LHC </th>
|
|
|
<th> unknown
|
|
|
</th></tr></table>
|
|
|
|
|
|
## Brief Explanation
|
|
|
|
|
|
|
|
|
Layout, as described in [ s9.3 of the Haskell 98 Report](http://www.haskell.org/onlinereport/syntax-iso.html#sect9.3), has a rule
|
|
|
|
|
|
```wiki
|
|
|
L ({n}:ts) (m:ms) = { : (L ts (n:m:ms)) if n > m
|
|
|
```
|
|
|
|
|
|
See [ExtensionDescriptionHowto](extension-description-howto) for information on how to write these extension descriptions. Please add any new extensions to the list of [HaskellExtensions](haskell-extensions).
|
|
|
|
|
|
|
|
|
## Brief Explanation
|
|
|
|
|
|
GHC and Hugs change the above \> to ≥ if the previous token was `do`, but not if it was `let`, `where` or `of`.
|
|
|
This allows uses like short-circuiting returns *a la* imperative languages:
|
|
|
|
|
|
```wiki
|
|
|
foo = do
|
|
|
...
|
|
|
if cond then return () else do
|
|
|
...
|
|
|
...
|
|
|
```
|
|
|
|
|
|
Ross says: I think [NondecreasingIndentation](nondecreasing-indentation) refers to changing \> in the H98 (s9.3) rule
|
|
|
|
|
|
and a style often used with the [ForeignFunctionInterface](foreign-function-interface):
|
|
|
|
|
|
```wiki
|
|
|
foo = do
|
|
|
alloca $ \foo -> do
|
|
|
writeStuff foo
|
|
|
alloca $ \bar -> do
|
|
|
writeStuff bar
|
|
|
alloca $ \baz -> do
|
|
|
....
|
|
|
L ({n}:ts) (m:ms) = { : (L ts (n:m:ms)) if n > m
|
|
|
```
|
|
|
|
|
|
|
|
|
but not
|
|
|
to ≥. GHC and Hugs do this if the previous token was "do", i.e. they
|
|
|
accept
|
|
|
|
|
|
|
|
|
```wiki
|
|
|
g x = case x of
|
|
|
Just y -> case y of
|
|
|
Just z -> z
|
|
|
f = do
|
|
|
x <- readLn
|
|
|
withFoo $ \ y -> do
|
|
|
z <- readLn
|
|
|
print (x+y+z)
|
|
|
```
|
|
|
|
|
|
|
|
|
Doing the same thing after `let` or `where` would invalidate legal Haskell 98 programs, e.g.
|
|
|
but not
|
|
|
|
|
|
```wiki
|
|
|
class C a where
|
|
|
|
|
|
f x = x
|
|
|
```wiki
|
|
|
g x = case x of
|
|
|
Just y -> case y of
|
|
|
Just z -> z
|
|
|
```
|
|
|
|
|
|
## References
|
|
|
|
|
|
- Somewhat related issue: [DoAndIfThenElse](do-and-if-then-else)
|
|
|
|
|
|
## Pros
|
|
|
|
|
|
|
|
|
- Just a minor adjustment
|
|
|
- Pro
|
|
|
|
|
|
## Cons
|
|
|
|
|
|
- If symbols not handled uniformly, adds a special case in an already-obscure part of the language |
|
|
|
|
|
- Con
|
|
|
- Con |