Abstract
A compiler should warn if a function defined by pattern matching does not cover its inputs—that is, if there are missing or redundant patterns. Generating such warnings accurately is difficult for modern languages due to the myriad of language features that interact with pattern matching. This is especially true in Haskell, a language with a complicated pattern language that is made even more complex by extensions offered by the Glasgow Haskell Compiler (GHC). Although GHC has spent a significant amount of effort towards improving its pattern-match coverage warnings, there are still several cases where it reports inaccurate warnings.
We introduce a coverage checking algorithm called Lower Your Guards, which boils down the complexities of pattern matching into guard trees. While the source language may have many exotic forms of patterns, guard trees only have three different constructs, which vastly simplifies the coverage checking process. Our algorithm is modular, allowing for new forms of source-language patterns to be handled with little changes to the overall structure of the algorithm. We have implemented the algorithm in GHC and demonstrate places where it performs better than GHC’s current coverage checker, both in accuracy and performance.
Supplemental Material
Available for Download
An Appendix describing three additional extensions: Literals, Newtypes and a strict source language.
- Lennart Augustsson. 1985. Compiling pattern matching. In Functional Programming Languages and Computer Architecture, Jean-Pierre Jouannaud (Ed.). Springer Berlin Heidelberg, Berlin, Heidelberg, 368-381.Google Scholar
- Jesper Cockx and Andreas Abel. 2018. Elaborating Dependent (Co)Pattern Matching. Proc. ACM Program. Lang. 2, ICFP, Article 75 ( July 2018 ), 30 pages. https://doi.org/10.1145/3236770 Google Scholar
Digital Library
- Joshua Dunfield. 2007. A Unified System of Type Refinements. Ph.D. Dissertation. Carnegie Mellon University. CMU-CS-07-129.Google Scholar
- Richard A. Eisenberg and Jan Stolarek. 2014. Promoting Functions to Type Families in Haskell. In Proceedings of the 2014 ACM SIGPLAN Symposium on Haskell (Gothenburg, Sweden) (Haskell '14). Association for Computing Machinery, New York, NY, USA, 95-106. https://doi.org/10.1145/2633357.2633361 Google Scholar
Digital Library
- Richard A. Eisenberg and Stephanie Weirich. 2012. Dependently Typed Programming with Singletons. In Proceedings of the 2012 Haskell Symposium (Copenhagen, Denmark) ( Haskell '12). ACM, New York, NY, USA, 117-130. https: //doi.org/10.1145/2364506.2364522 Google Scholar
Digital Library
- Jacques Garrigue and Jacques Le Normand. 2011. Adding GADTs to OCaml: the direct approach. In Workshop on ML.Google Scholar
- GHC issue. 2015a. New pattern-match check can be non-performant. https://gitlab.haskell.org/ghc/ghc/issues/11195Google Scholar
- GHC issue. 2015b. No non-exhaustive pattern match warning given for empty case analysis. https://gitlab.haskell.org/ghc/ ghc/issues/10746Google Scholar
- GHC issue. 2016a. In a record-update construct:ghc-stage2: panic! (the 'impossible' happened). https://gitlab.haskell.org/ ghc/ghc/issues/12957Google Scholar
- GHC issue. 2016b. Inaccessible RHS warning is confusing for users. https://gitlab.haskell.org/ghc/ghc/issues/13021Google Scholar
- GHC issue. 2016c. Pattern coverage checker ignores dictionary arguments. https://gitlab.haskell.org/ghc/ghc/issues/12949Google Scholar
- GHC issue. 2016d. Pattern match incompleteness / inaccessibility discrepancy. https://gitlab.haskell.org/ghc/ghc/issues/ 11984Google Scholar
- GHC issue. 2016e. Representation of value set abstractions as trees causes performance issues. https://gitlab.haskell.org/ ghc/ghc/issues/11528Google Scholar
- GHC issue. 2017a.-Woverlapping-patterns warns on wrong patterns for Int. https://gitlab.haskell.org/ghc/ghc/issues/14546Google Scholar
- GHC issue. 2017b. COMPLETE sets don't work at all with data family instances. https://gitlab.haskell.org/ghc/ghc/issues/ 14059Google Scholar
- GHC issue. 2017c. COMPLETE sets nerf redundant pattern-match warnings. https://gitlab.haskell.org/ghc/ghc/issues/13965Google Scholar
- GHC issue. 2017d. Incorrect pattern match warning on nested GADTs. https://gitlab.haskell.org/ghc/ghc/issues/14098Google Scholar
- GHC issue. 2017e. Pattern match checker mistakenly concludes pattern match on pattern synonym is unreachable. https://gitlab.haskell.org/ghc/ghc/issues/14253Google Scholar
- GHC issue. 2017f. Pattern synonym exhaustiveness checks don't play well with EmptyCase. https://gitlab.haskell.org/ghc/ ghc/issues/13717Google Scholar
- GHC issue. 2017g. Wildcard patterns and COMPLETE sets can lead to misleading redundant pattern-match warnings. https://gitlab.haskell.org/ghc/ghc/issues/13363Google Scholar
- GHC issue. 2018a.-Wincomplete-patterns gets confused when combining GADTs and pattern guards. https://gitlab.haskell. org/ghc/ghc/issues/15385Google Scholar
- GHC issue. 2018b. Bogus-Woverlapping-patterns warning with OverloadedStrings. https://gitlab.haskell.org/ghc/ghc/ issues/15713Google Scholar
- GHC issue. 2018c. Compiling a function with a lot of alternatives bottlenecks on insertIntHeap. https://gitlab.haskell.org/ ghc/ghc/issues/14667Google Scholar
- GHC issue. 2018d. Completeness of View Patterns With a Complete Set of Output Patterns. https://gitlab.haskell.org/ghc/ ghc/issues/15884Google Scholar
- GHC issue. 2018e. EmptyCase thinks pattern match involving type family is not exhaustive, when it actually is. https: //gitlab.haskell.org/ghc/ghc/issues/14813Google Scholar
- GHC issue. 2018f. Erroneous “non-exhaustive pattern match” using nested GADT with strictness annotation. https: //gitlab.haskell.org/ghc/ghc/issues/15305Google Scholar
- GHC issue. 2018g. Inconsistency w.r.t. coverage checking warnings for EmptyCase under unsatisfiable constraints. https: //gitlab.haskell.org/ghc/ghc/issues/15450Google Scholar
- GHC issue. 2018h. Inconsistent pattern-match warnings when using guards versus case expressions. https://gitlab.haskell. org/ghc/ghc/issues/15753Google Scholar
- GHC issue. 2018i. nonVoid is too conservative w.r.t. strict argument types. https://gitlab.haskell.org/ghc/ghc/issues/15584Google Scholar
- GHC issue. 2018j. “ Pattern match has inaccessible right hand side” with TypeRep. https://gitlab.haskell.org/ghc/ghc/issues/ 14851Google Scholar
- GHC issue. 2019a. 67-pattern COMPLETE pragma overwhelms the pattern match checker. https://gitlab.haskell.org/ghc/ ghc/issues/17096Google Scholar
- GHC issue. 2019b. Add Luke Maranget's series in “Warnings for Pattern Matching”. https://gitlab.haskell.org/ghc/ghc/ issues/17264Google Scholar
- GHC issue. 2019c. `case (x :: Void) of_-> ()` should be flagged as redundant. https://gitlab.haskell.org/ghc/ghc/issues/17376Google Scholar
- GHC issue. 2019d. GHC thinks pattern match is exhaustive. https://gitlab.haskell.org/ghc/ghc/issues/16289Google Scholar
- GHC issue. 2019e. Incorrect non-exhaustive pattern warning with PatternSynonyms. https://gitlab.haskell.org/ghc/ghc/ issues/16129Google Scholar
- GHC issue. 2019f. Minimality of missing pattern set depends on constructor declaration order. https://gitlab.haskell.org/ ghc/ghc/issues/17386Google Scholar
- GHC issue. 2019g. Panic during tyConAppArgs. https://gitlab.haskell.org/ghc/ghc/issues/17112Google Scholar
- GHC issue. 2019h. Pattern-match checker : True /= False. https://gitlab.haskell.org/ghc/ghc/issues/17251Google Scholar
- GHC issue. 2019i. Pattern match checking open unions. https://gitlab.haskell.org/ghc/ghc/issues/17149Google Scholar
- GHC issue. 2019j. Pattern match overlap checking doesn't consider-XBangPatterns. https://gitlab.haskell.org/ghc/ghc/ issues/17234Google Scholar
- GHC issue. 2019k. Pattern match warnings are per Match, not per GRHS. https://gitlab.haskell.org/ghc/ghc/issues/17465Google Scholar
- GHC issue. 2019l. PmCheck treats Newtype patterns the same as constructors. https://gitlab.haskell.org/ghc/ghc/issues/ 17248Google Scholar
- GHC issue. 2019m. Strictness of pattern synonym matches and pattern-match checking. https://gitlab.haskell.org/ghc/ghc/ issues/17357Google Scholar
- GHC issue. 2020a.-Wincomplete-record-updates ignores context. https://gitlab.haskell.org/ghc/ghc/issues/17783Google Scholar
- GHC issue. 2020b. Pattern match checker stumbles over reasonably tricky pattern-match. https://gitlab.haskell.org/ghc/ ghc/issues/17703Google Scholar
- GHC issue. 2020c. Pattern match coverage checker allocates twice as much for trivial program with instance constraint vs. without. https://gitlab.haskell.org/ghc/ghc/issues/17891Google Scholar
- GHC issue. 2020d. Pattern match warning emitted twice. https://gitlab.haskell.org/ghc/ghc/issues/17646Google Scholar
- GHC team. 2020. COMPLETE pragmas. https://downloads.haskell.org/~ghc/8.8.3/docs/html/users_guide/glasgow_exts. html#pragma-COMPLETEGoogle Scholar
- Pavel Kalvoda and Tom Sydney Kerckhove. 2019. Structural and semantic pattern matching analysis in Haskell. arXiv: 1909. 04160 [cs.PL]Google Scholar
- Georgios Karachalias, Tom Schrijvers, Dimitrios Vytiniotis, and Simon Peyton Jones. 2015. GADTs meet their match (extended version). Technical Report. KU Leuven. https://people.cs.kuleuven.be/~tom.schrijvers/Research/papers/icfp2015.pdfGoogle Scholar
- Luc Maranget. 2007. Warnings for pattern matching. Journal of Functional Programming 17 ( 2007 ), 387-421. Issue 3.Google Scholar
- Ulf Norell. 2007. Towards a practical programming language based on dependent type theory. Ph.D. Dissertation. Department of Computer Science and Engineering, Chalmers University of Technology, SE-412 96 Göteborg, Sweden.Google Scholar
- Nicolas Oury. 2007. Pattern Matching Coverage Checking with Dependent Types Using Set Approximations. In Proceedings of the 2007 Workshop on Programming Languages Meets Program Verification (Freiburg, Germany) (PLPV '07). Association for Computing Machinery, New York, NY, USA, 47-56. https://doi.org/10.1145/1292597.1292606 Google Scholar
Digital Library
- Matthew Pickering, Gergő Érdi, Simon Peyton Jones, and Richard A. Eisenberg. 2016. Pattern Synonyms. In Proceedings of the 9th International Symposium on Haskell (Nara, Japan) ( Haskell 2016 ). Association for Computing Machinery, New York, NY, USA, 80-91. https://doi.org/10.1145/2976002.2976013 Google Scholar
Digital Library
- John Rushby, Sam Owre, and Natarajan Shankar. 1998. Subtypes for specifications: Predicate subtyping in PVS. IEEE Transactions on Software Engineering 24, 9 ( 1998 ), 709-720.Google Scholar
Digital Library
- R. C. Sekar, R. Ramesh, and I. V. Ramakrishnan. 1995. Adaptive Pattern Matching. SIAM J. Comput. 24, 6 (Dec. 1995 ), 1207-1234. https://doi.org/10.1137/S0097539793246252 Google Scholar
Digital Library
- Peter Sestoft. 1996. ML pattern match compilation and partial evaluation. In Partial Evaluation. Springer, 446-464.Google Scholar
- Matthieu Sozeau. 2010. Equations: A Dependent Pattern-Matching Compiler. In Interactive Theorem Proving, Matt Kaufmann and Lawrence C. Paulson (Eds.). Springer Berlin Heidelberg, Berlin, Heidelberg, 419-434.Google Scholar
- Matthieu Sozeau and Cyprien Mangin. 2019. Equations Reloaded: High-Level Dependently-Typed Functional Programming and Proving in Coq. Proc. ACM Program. Lang. 3, ICFP, Article 86 ( July 2019 ), 29 pages. https://doi.org/10.1145/3341690 Google Scholar
Digital Library
- Niki Vazou, Eric L. Seidel, Ranjit Jhala, Dimitrios Vytiniotis, and Simon Peyton-Jones. 2014. Refinement Types for Haskell. In Proceedings of the 19th ACM SIGPLAN International Conference on Functional Programming (Gothenburg, Sweden) (ICFP '14). ACM, New York, NY, USA, 269-282. https://doi.org/10.1145/2628136.2628161 Google Scholar
Digital Library
- Niki Vazou, Anish Tondwalkar, Vikraman Choudhury, Ryan G. Scott, Ryan R. Newton, Philip Wadler, and Ranjit Jhala. 2017. Refinement Reflection: Complete Verification with SMT. Proc. ACM Program. Lang. 2, POPL, Article 53 ( Dec. 2017 ), 31 pages. https://doi.org/10.1145/3158141 Google Scholar
Digital Library
- Dimitrios Vytiniotis, Simon Peyton Jones, Tom Schrijvers, and Martin Sulzmann. 2011. OutsideIn(X): Modular Type Inference with Local Assumptions. J. Funct. Program. 21, 4-5 ( Sept. 2011 ), 333-412. https://doi.org/10.1017/S0956796811000098 Google Scholar
Digital Library
- Hongwei Xi. 1998a. Dead Code Elimination Through Dependent Types. In Proceedings of the First International Workshop on Practical Aspects of Declarative Languages (PADL '99). Springer-Verlag, London, UK, 228-242.Google Scholar
Cross Ref
- Hongwei Xi. 1998b. Dependent Types in Practical Programming. Ph.D. Dissertation. Carnegie Mellon University.Google Scholar
Digital Library
- Hongwei Xi. 2003. Dependently typed pattern matching. Journal of Universal Computer Science 9 ( 2003 ), 851-872.Google Scholar
- Hongwei Xi, Chiyan Chen, and Gang Chen. 2003. Guarded Recursive Datatype Constructors. In Proceedings of the 30th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (New Orleans, Louisiana, USA) ( POPL '03). ACM, New York, NY, USA, 224-235. https://doi.org/10.1145/604131.604150 Google Scholar
Digital Library
- Hongwei Xi and Frank Pfenning. 1998. Eliminating Array Bound Checking through Dependent Types. In Proceedings of the ACM SIGPLAN 1998 Conference on Programming Language Design and Implementation (Montreal, Quebec, Canada) ( PLDI '98). Association for Computing Machinery, New York, NY, USA, 249-257. https://doi.org/10.1145/277650.277732 Google Scholar
Digital Library
- Brent A. Yorgey, Stephanie Weirich, Julien Cretin, Simon Peyton Jones, Dimitrios Vytiniotis, and José Pedro Magalhães. 2012. Giving Haskell a Promotion. In Proceedings of the 8th ACM SIGPLAN Workshop on Types in Language Design and Implementation (Philadelphia, Pennsylvania, USA) ( TLDI '12). ACM, New York, NY, USA, 53-66. https://doi.org/10.1145/ 2103786.2103795 Google Scholar
Digital Library
Index Terms
Lower your guards: a compositional pattern-match coverage checker
Recommendations
Strength Induction in a Haskell Program Verifier
Haskell employs a melange of strict and non-strict evaluation semantics, hence a Haskell verifier should be capable of checking assumptions that program variables may or may not denote well-defined values. The paper introduces a new strategy, called ...
Compositional compiler construction
We describe an implementation of an Oberon0 compiler using the techniques proposed in the CoCoCo project. The compiler is constructed out of a collection of pre-compiled, statically type-checked language-definition fragments written in Haskell. Oberon0 ...
Layout-sensitive language extensibility with SugarHaskell
Haskell '12: Proceedings of the 2012 Haskell SymposiumProgrammers need convenient syntax to write elegant and concise programs. Consequently, the Haskell standard provides syntactic sugar for some scenarios (e.g., do notation for monadic code), authors of Haskell compilers provide syntactic sugar for more ...






Comments