2.87 s[treefmt-check] There is usually one project per repository, but sometimes a project may be split across multiple repositories. It’s unlikely that more than one project would be in the same repository.
2.87 s[treefmt-check] Documentation is written using [Haddock](https://haskell-haddock.readthedocs.io/), and it’s helpful to add Doctest examples, as described in the “testing” section below.
2.87 s[treefmt-check] -__NB__: Haddock isn’t Markdown! But the similarities can make it easy to forget sometimes. Please try to review your doc changes using [`cabal haddock-project`](https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-haddock-project) before submitting them.
2.87 s[treefmt-check] +**NB**: Haddock isn’t Markdown! But the similarities can make it easy to forget sometimes. Please try to review your doc changes using [`cabal haddock-project`](https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-haddock-project) before submitting them.
2.87 s[treefmt-check] This is a versioning system that’s compatible with [the Haskell Package Versioning Policy](https://pvp.haskell.org/), but tries to prevent more issues with dependencies.
2.87 s[treefmt-check] -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
2.87 s[treefmt-check] +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
2.87 s[treefmt-check] @@ -54,6 +54,7 @@ This largely follows the [Haskell Package Versioning Policy](https://pvp.haskell
2.87 s[treefmt-check] The package version always has four components, `A.B.C.D`[^1]. The first three correspond to those required by PVP, while the fourth matches the “patch” component from [Semantic Versioning](https://semver.org/).
2.87 s[treefmt-check] - bumping `C` is a **C**ompatible change, and
2.87 s[treefmt-check] @@ -116,11 +117,11 @@ Each of these cases is covered in the following sections with justifications, bu
2.87 s[treefmt-check] - a “persisting” type or class means that the type or class existed in a release prior to the addition, or continues to exist in the release containing the removal
2.87 s[treefmt-check] -| [`import`](#imports) | `A`/`C`/`D` | `A`/`D` | ✔ | `C` when it’s part of a new module, `D` when there is persisting import for the same module |
2.87 s[treefmt-check] +| [`import`](#imports) | `A`/`C`/`D` | `A`/`D` | ✔ | `C` when it’s part of a new module, `D` when there is persisting import for the same module |
2.87 s[treefmt-check] | [`instance`](#instances) | `A`/`C` | `A` | | only when applied to persisting types & classes, `C` when it’s part of a new module |
2.87 s[treefmt-check] -| [`module`](#modules) | `C` | `A`/`B` | ✔ | `B` when the removed module had _zero_ imports |
2.87 s[treefmt-check] -| `-Werror` | `A`* | `D` | | **NB**: If you use `-Werror`, any change to the package is an `A` change |
2.87 s[treefmt-check] +| [`module`](#modules) | `C` | `A`/`B` | ✔ | `B` when the removed module had _zero_ imports |
2.87 s[treefmt-check] +| `-Werror` | `A`\* | `D` | | **NB**: If you use `-Werror`, any change to the package is an `A` change |
2.87 s[treefmt-check] | [constructor](#constructors) | `B`/`C` | `B` | | only when applied to persisting type, `C` when there were previously no exported constructors for the type |
2.87 s[treefmt-check] | field | `B` | `B` | | only when applied to persisting type |
2.87 s[treefmt-check] @@ -137,9 +138,9 @@ Each of these cases is covered in the following sections with justifications, bu
2.87 s[treefmt-check] -| [dependency bound](#dependencies) | `D` | `A`/`D` | ✔ | `A` when new `A` or non-strict `B` version is supported, and for certain other libraries |
2.88 s[treefmt-check] +| [dependency bound](#dependencies) | `D` | `A`/`D` | ✔ | `A` when new `A` or non-strict `B` version is supported, and for certain other libraries |
2.88 s[treefmt-check] | [compiler bound](#compiler-bounds) | `B`/`D` | `D` | | `D` when “guarded” by a corresponding non-reinstallable dependency tightening |
2.88 s[treefmt-check] | [constraint](#constraints) | `B` | `D` | | **TODO**: type variable defaulting may be an issue here |
2.88 s[treefmt-check] | `type role` | `B` | `D` | ? | “inferred” should be treated as between `representational` and `phantom` |
2.88 s[treefmt-check] @@ -286,7 +287,7 @@ Haskell does type resolution independently of constraints. It then sees if the t
2.88 s[treefmt-check] This is a good example of the difference between “additions to the API” and “non-breaking changes to the API”. This makes a function applicable in more situations, but doesn’t add anything to the API.
2.88 s[treefmt-check] -**FIXME**: I think this might not be true with [type variable defaulting](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/type_defaulting.html). For example, if you weaken a constraint from `RealFloat` to `Num`, and a consumer is using `default (Natural, Double)`, the switch from resolving `Double` to resolving `Natural` can then introduce a runtime failure when they call `negate`. There are mechanisms to disable defaulting, like `default ()` or requiring `-Werror=type-defaults`, but those must be applied in the consumer, not the definer.
2.88 s[treefmt-check] +**FIXME**: I think this might not be true with [type variable defaulting](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/type_defaulting.html). For example, if you weaken a constraint from `RealFloat` to `Num`, and a consumer is using `default (Natural, Double)`, the switch from resolving `Double` to resolving `Natural` can then introduce a runtime failure when they call `negate`. There are mechanisms to disable defaulting, like `default ()` or requiring `-Werror=type-defaults`, but those must be applied in the consumer, not the definer.
2.90 s> There is usually one project per repository, but sometimes a project may be split across multiple repositories. It’s unlikely that more than one project would be in the same repository.
2.90 s> Documentation is written using [Haddock](https://haskell-haddock.readthedocs.io/), and it’s helpful to add Doctest examples, as described in the “testing” section below.
2.90 s> -__NB__: Haddock isn’t Markdown! But the similarities can make it easy to forget sometimes. Please try to review your doc changes using [`cabal haddock-project`](https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-haddock-project) before submitting them.
2.90 s> +**NB**: Haddock isn’t Markdown! But the similarities can make it easy to forget sometimes. Please try to review your doc changes using [`cabal haddock-project`](https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-haddock-project) before submitting them.
2.90 s> This is a versioning system that’s compatible with [the Haskell Package Versioning Policy](https://pvp.haskell.org/), but tries to prevent more issues with dependencies.
2.90 s> -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
2.90 s> +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
2.90 s> @@ -54,6 +54,7 @@ This largely follows the [Haskell Package Versioning Policy](https://pvp.haskell
2.90 s> The package version always has four components, `A.B.C.D`[^1]. The first three correspond to those required by PVP, while the fourth matches the “patch” component from [Semantic Versioning](https://semver.org/).
2.90 s> - bumping `C` is a **C**ompatible change, and
2.90 s> @@ -116,11 +117,11 @@ Each of these cases is covered in the following sections with justifications, bu
2.90 s> - a “persisting” type or class means that the type or class existed in a release prior to the addition, or continues to exist in the release containing the removal
2.90 s> -| [`import`](#imports) | `A`/`C`/`D` | `A`/`D` | ✔ | `C` when it’s part of a new module, `D` when there is persisting import for the same module |
2.90 s> +| [`import`](#imports) | `A`/`C`/`D` | `A`/`D` | ✔ | `C` when it’s part of a new module, `D` when there is persisting import for the same module |
2.90 s> | [`instance`](#instances) | `A`/`C` | `A` | | only when applied to persisting types & classes, `C` when it’s part of a new module |
2.90 s> -| [`module`](#modules) | `C` | `A`/`B` | ✔ | `B` when the removed module had _zero_ imports |
2.90 s> -| `-Werror` | `A`* | `D` | | **NB**: If you use `-Werror`, any change to the package is an `A` change |
2.90 s> +| [`module`](#modules) | `C` | `A`/`B` | ✔ | `B` when the removed module had _zero_ imports |
2.90 s> +| `-Werror` | `A`\* | `D` | | **NB**: If you use `-Werror`, any change to the package is an `A` change |
2.90 s> | [constructor](#constructors) | `B`/`C` | `B` | | only when applied to persisting type, `C` when there were previously no exported constructors for the type |
2.90 s> | field | `B` | `B` | | only when applied to persisting type |
2.90 s> @@ -137,9 +138,9 @@ Each of these cases is covered in the following sections with justifications, bu
2.90 s> -| [dependency bound](#dependencies) | `D` | `A`/`D` | ✔ | `A` when new `A` or non-strict `B` version is supported, and for certain other libraries |
2.90 s> +| [dependency bound](#dependencies) | `D` | `A`/`D` | ✔ | `A` when new `A` or non-strict `B` version is supported, and for certain other libraries |
2.90 s> | [compiler bound](#compiler-bounds) | `B`/`D` | `D` | | `D` when “guarded” by a corresponding non-reinstallable dependency tightening |
2.90 s> | [constraint](#constraints) | `B` | `D` | | **TODO**: type variable defaulting may be an issue here |
2.90 s> | `type role` | `B` | `D` | ? | “inferred” should be treated as between `representational` and `phantom` |
2.90 s> @@ -286,7 +287,7 @@ Haskell does type resolution independently of constraints. It then sees if the t
2.90 s> This is a good example of the difference between “additions to the API” and “non-breaking changes to the API”. This makes a function applicable in more situations, but doesn’t add anything to the API.
2.90 s> -**FIXME**: I think this might not be true with [type variable defaulting](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/type_defaulting.html). For example, if you weaken a constraint from `RealFloat` to `Num`, and a consumer is using `default (Natural, Double)`, the switch from resolving `Double` to resolving `Natural` can then introduce a runtime failure when they call `negate`. There are mechanisms to disable defaulting, like `default ()` or requiring `-Werror=type-defaults`, but those must be applied in the consumer, not the definer.
2.90 s> +**FIXME**: I think this might not be true with [type variable defaulting](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/type_defaulting.html). For example, if you weaken a constraint from `RealFloat` to `Num`, and a consumer is using `default (Natural, Double)`, the switch from resolving `Double` to resolving `Natural` can then introduce a runtime failure when they call `negate`. There are mechanisms to disable defaulting, like `default ()` or requiring `-Werror=type-defaults`, but those must be applied in the consumer, not the definer.