Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,869
    • Issues 4,869
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 456
    • Merge requests 456
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #17216
Closed
Open
Created Sep 19, 2019 by Guillaume Bouchard@guibouReporter

Pattern exhaustivity check for simple arithmetic

Motivation

The following:

foo :: Int -> Bool
foo i
  | i < 0 = True
  | i == 0 = True
  | i > 0 = True

results on the following warning:

 Pattern match(es) are non-exhaustive
    In an equation for ‘foo’: Patterns not matched: _
  |
2 | foo i
  | ^^^^^...

When the guard is indeed exhaustive. One solution is to replace the latest case by otherwise, but more often than never it leads to subtle bug when a case was indeed missing.

Proposal

I'd like the exhaustivity checker to not complain in this case.

However I realize that it is not a trivial task. I know that it is exhaustive because I know the mathematical rules of comparison for integer, but GHC has no reason to think that it is exhaustive. Actually, someone could implement really weird Eq and Ord instances which makes this guard not exhaustive.

May it be possible to extend the COMPLETE pragma for some instances and using variables? For example (imaginary syntax):

{-# COMPLETE forall x :: Int. (<x) (>x) (==x) #-} 
-- For symmetry
{-# COMPLETE forall x :: Int. (x<) (x>) (x==) #-} 
Edited Sep 19, 2019 by Guillaume Bouchard
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking