|
|
# Proposal: NoNPlusKPatterns
|
|
|
|
|
|
<table><tr><th> Ticket </th>
|
|
|
<th>[\#130](https://gitlab.haskell.org//haskell/prime/issues/130)</th></tr>
|
|
|
<tr><th> Dependencies </th>
|
|
|
<th> none
|
|
|
</th></tr>
|
|
|
<tr><th> Related </th>
|
|
|
<th> ViewPatterns
|
|
|
</th></tr></table>
|
|
|
|
|
|
## Compiler support
|
|
|
|
|
|
<table><tr><th> GHC </th>
|
|
|
<th> none
|
|
|
</th></tr>
|
|
|
<tr><th> nhc98 </th>
|
|
|
<th> full (`--nonplusk`)
|
|
|
</th></tr>
|
|
|
<tr><th> Hugs </th>
|
|
|
<th> none?
|
|
|
</th></tr>
|
|
|
<tr><th> UHC </th>
|
|
|
<th> full (doesn't support n+k patterns at all)
|
|
|
</th></tr>
|
|
|
<tr><th> JHC </th>
|
|
|
<th> none?
|
|
|
</th></tr>
|
|
|
<tr><th> LHC </th>
|
|
|
<th> none?
|
|
|
</th></tr></table>
|
|
|
|
|
|
## Summary
|
|
|
|
|
|
|
|
|
Remove `n+k` patterns.
|
|
|
|
|
|
## Description
|
|
|
|
|
|
`n+k` patterns provide a concise, natural, and familiar notation for recursion over naturals. When used with non-negative types, such as `Word`, they allow functions to be cleanly defined using non-overlapping patterns.
|
|
|
|
|
|
|
|
|
However, `n+k` patterns are a non-orthogonal feature. No other pattern has special notation like this, although there is a ViewPatterns extension which does something not entirely dissimilar in a general way.
|
|
|
|
|
|
|
|
|
The `+` symbol is being abused here; it doesn't really mean `+`, and if `+` happens to be bound to something other than `Prelude.+` the notation's behaviour doesn't change. Counterintuitively, the desugaring *does* include references to a number of *other*`Prelude` definitions: `Integral`, `-` and `>=`.
|
|
|
|
|
|
|
|
|
Working on all `Integral` types is inconsistent with the `n >= 0` condition, which means that `n` is really a natural number.
|
|
|
|
|
|
|
|
|
There has long been a general consensus in the community that `n+k` patterns should be removed. Indeed, the report already admits "Many people feel that n+k patterns should not be used. These patterns may be removed or changed in future versions of Haskell." (Haskell 98 Revised Report, Section 3.17.2).
|
|
|
|
|
|
## References
|
|
|
|
|
|
[ Haskell 98 Revised Report, Section 3.17.2](http://haskell.org/onlinereport/exps.html#sect3.17.2)
|
|
|
|
|
|
## Report Delta
|
|
|
|
|
|
|
|
|
In [ Section 3.17.1](http://haskell.org/onlinereport/exps.html#sect3.17.1) replace:
|
|
|
|
|
|
```
|
|
|
|
|
|
pat -> var + integer (successor pattern)
|
|
|
| pat0
|
|
|
```
|
|
|
|
|
|
|
|
|
with:
|
|
|
|
|
|
```
|
|
|
|
|
|
pat -> pat0
|
|
|
```
|
|
|
|
|
|
|
|
|
In [ Section 3.17.2](http://haskell.org/onlinereport/exps.html#sect3.17.2) remove:
|
|
|
|
|
|
1. Matching an `n+k` pattern (where `n` is a variable and `k` is a positive integer literal) against a value `v` succeeds if `x >= k`, resulting in the binding of `n` to `x - k`, and fails otherwise. Again, the functions `>=` and `-` are overloaded, depending on the type of the pattern. The match diverges if the comparison diverges.
|
|
|
|
|
|
|
|
|
The interpretation of the literal `k` is the same as in numeric literal patterns, except that only integer literals are allowed.
|
|
|
|
|
|
|
|
|
and renumber.
|
|
|
|
|
|
|
|
|
In [ Section 3.17.2](http://haskell.org/onlinereport/exps.html#sect3.17.2) remove:
|
|
|
|
|
|
- An `n+k` pattern can only be matched against a value in the class `Integral`.
|
|
|
|
|
|
|
|
|
Many people feel that `n+k` patterns should not be used. These patterns may be removed or changed in future versions of Haskell.
|
|
|
|
|
|
|
|
|
In [ Section 3.17.3](http://haskell.org/onlinereport/exps.html#sect3.17.3) remove:
|
|
|
|
|
|
```
|
|
|
|
|
|
(s)
|
|
|
case v of { x+k -> e; _ -> e' }
|
|
|
= if v >= k then (\x -> e) (v-k) else e'
|
|
|
where k is a numeric literal
|
|
|
```
|
|
|
|
|
|
|
|
|
In [ Section 4.4.3.2](http://haskell.org/onlinereport/decls.html#sect4.4.3.2) remove:
|
|
|
|
|
|
**A note about syntax.**
|
|
|
|
|
|
|
|
|
It is usually straightforward to tell whether a binding is a pattern binding or a function binding, but the existence of `n+k` patterns sometimes confuses the issue. Here are four examples:
|
|
|
|
|
|
```wiki
|
|
|
x + 1 = ... -- Function binding, defines (+)
|
|
|
-- Equivalent to (+) x 1 = ...
|
|
|
|
|
|
(x + 1) = ... -- Pattern binding, defines x
|
|
|
|
|
|
(x + 1) * y = ... -- Function binding, defines (*)
|
|
|
-- Equivalent to (*) (x+1) y = ...
|
|
|
|
|
|
(x + 1) y = ... -- Function binding, defines (+)
|
|
|
-- Equivalent to (+) x 1 y = ...
|
|
|
```
|
|
|
|
|
|
|
|
|
The first two can be distinguished because a pattern binding has a pat0 on the left hand side, not a pat —- the former cannot be an unparenthesised `n+k` pattern. |