Skip to content

Use NonEmpty lists in more places in the GHC API

After GHC 8.2 is released and we drop support for building GHC with 7.10, we should try to use Data.List.NonEmpty in more places in the GHC API. I ran into this issue recently when using some functions from ListSetOps:

removeDups :: (a -> a -> Ordering) -> [a] -> ([a], [[a]]) 
findDupsEq :: (a -> a -> Bool) -> [a] -> [[a]]
equivClasses :: (a -> a -> Ordering) -> [a] -> [[a]] 

These type signatures are terrible. Really, they should be:

removeDups :: (a -> a -> Ordering) -> [a] -> ([a], [NonEmpty a]) 
findDupsEq :: (a -> a -> Bool) -> [a] -> [NonEmpty a]
equivClasses :: (a -> a -> Ordering) -> [a] -> [NonEmpty a] 

Since 90% of the time, the first thing you do after finding duplicates is to take a representative from the duplicate set. With lists, this requires the partial operation head, but with NonEmpty, this can be total like it was intended to be.

Here are a few suggestions where we could make use of NonEmpty:

  • ListSetOps as above
  • MatchGroup's mg_alts
  • GRHSs's grhssGRHSs (NB: I (@sgraf812) really like how grhssGRHSs grhss rolls off the tongue)

I'm sure there are other places in the API that could benefit from NonEmpty, so if you have any suggestions, please leave them in the list above.

Trac metadata
Trac field Value
Version 8.3
Type Task
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
Edited by Sebastian Graf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information