CLC has approved the proposal to
add {-# WARNING #-}
to Data.List.{head,tail}
. This means that the existing users of these functions will receive a compile-time warning about their partiality.
The change is scheduled for GHC 9.8.
This is not a breaking change, unless a package forces -Werror
.
If you don't want to change any Haskell code and want to carry on with using Data.List.{head,tail}
:
-
If you use
-Werror
, set-Wwarn=x-partial
to downgrade this area of compiler messages from errors to warnings, so that your build can succeed. Note thatx-partial
is a new group of warnings, introduced in GHC 9.8, so you might need to additionally set-Wno-unrecognised-warning-flags
or-Wwarn=unrecognised-warning-flags
to maintain backward compatibility with older GHC releases. -
If you are annoyed by warnings, set
-Wno-x-partial
to quash this area of compiler messages. Use-Wno-unrecognised-warning-flags
to maintain backward compatibility with older GHC releases. To disable the warnings once and forever in GHCi, put:set -Wno-x-partial -Wno-unrecognised-warning-flags
into~/.ghci
config file. Beware that this also disables any other warnings in the custom-x-partial
warning group!
If you are happy to change code to eliminate warning messages:
-
The easiest way to migrate away from
tail
is to replace it withdrop 1
. This is a drop-in replacement unless you are relying ontail
's partiality. -
Instead of
head
you can use explicit pattern matching: replace anyhead foo
withcase foo of [] -> error "<explain, why it is impossible to encounter an empty list here>" hd : _ -> hd
-
Another option is to use
Data.List.uncons
orData.Maybe.listToMaybe
: replace anyhead foo
withmaybe (error "...") fst (uncons foo)
or
fromMaybe (error "...") (listToMaybe foo)
-
It is even better to enforce non-emptiness of the list in types, using
Data.List.NonEmpty
. This might however require non-local refactoring. -
If the list is guaranteed to be not only non-empty, but actually infinite, one can be benefit from enforcing this invariant in types as well. E. g., use
Stream
,streams
orinfinite-list
. -
As an ultimate measure you can hide
Prelude.{head,tail}
and define your own in a utility module, or useheadErr
andtailErr
fromSafe
.
Here is a template, which you can use when raising PRs against affected libraries.
Title: Avoid
Data.List.{head,tail}
CLC has approved the proposal to add
{-# WARNING #-}
toData.List.{head,tail}
(#87). It means that usage ofhead
andtail
will emit compile-time warnings starting from GHC 9.8.Migration guide and more info: https://github.com/haskell/core-libraries-committee/blob/main/guides/warning-for-head-and-tail.md