{"id":496,"date":"2022-08-30T15:02:19","date_gmt":"2022-08-30T15:02:19","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/09\/gadts-failed-exhaustiveness-checking-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:02:19","modified_gmt":"2022-08-30T15:02:19","slug":"gadts-failed-exhaustiveness-checking-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/gadts-failed-exhaustiveness-checking-collection-of-common-programming-errors\/","title":{"rendered":"GADT&#39;s failed exhaustiveness checking-Collection of common programming errors"},"content":{"rendered":"<p>The problem actually reported is:<\/p>\n<pre><code>Warning: Pattern match(es) are non-exhaustive\n         In an equation for `fun': Patterns not matched: Inl _\n<\/code><\/pre>\n<p>Which is true. You provide a case for the <code>Inr<\/code> constructor, but not the <code>Inl<\/code> constructor.<\/p>\n<p>What you&#8217;re hoping is that since there&#8217;s no way to provide a value of type <code>Sig B<\/code> that uses the <code>Inl<\/code> constructor (it would need an argument of type <code>Foo B<\/code>, but the only constructor for <code>Foo<\/code> is of type <code>Foo A<\/code>), that ghc will notice that you don&#8217;t need to handle the <code>Inl<\/code> constructor.<\/p>\n<p>The trouble is that due to bottom every type is inhabited. There <em>are<\/em> values of type <code>Sig B<\/code> that use the <code>Inl<\/code> constructor; there are even non-bottom values. They must <em>contain<\/em> bottom, but they are not themselves bottom. So it is possible for the program to be evaluating a call to <code>fun<\/code> that fails to match; that&#8217;s what ghc is warning about.<\/p>\n<p>So to fix that you need to change <code>fun<\/code> to something like this:<\/p>\n<pre><code>fun :: Sig B -&gt; Int\nfun (Inr Bar) = 1\nfun (Inl foo) = error \"whoops\"\n<\/code><\/pre>\n<p>But now of course if you later add <code>Baz :: Foo B<\/code> this function is a time bomb waiting to happen. It&#8217;s be nice for ghc to warn about <em>that<\/em>, but the only way to make that happen is to pattern match <code>foo<\/code> against a currently-exhaustive set of patterns. Unfortunately there <em>are<\/em> no valid patterns you can put there! <code>foo<\/code> is known to be of type <code>Foo B<\/code>, which is only inhabited by bottom, and you can&#8217;t write a pattern for bottom.<\/p>\n<p>But you could pass it to a function that accepts an argument of polymorphic type <code>Foo a<\/code>. That function could then match against all the currently-existing <code>Foo<\/code> constructors, so that you&#8217;ll get a warning if you later add one. Something like this:<\/p>\n<pre><code>fun :: Sig B -&gt; Int\nfun (Inr Bar) = 1\nfun (Inl foo) = errorFoo foo\n    where \n        errorFoo :: Foo a -&gt; b\n        errorFoo Foo = error \"whoops\"\n<\/code><\/pre>\n<p>Now You&#8217;ve properly handled all the constructors of <code>:+:<\/code> in <code>fun<\/code>, the &#8220;impossible&#8221; case simply errors out if it ever actually occurs and if you ever add <code>Baz :: Foo B<\/code> you get a warning about a non-exhaustive pattern in <code>errorFoo<\/code>, which is at least directing you to look at <code>fun<\/code> because it&#8217;s defined in an attached <code>where<\/code>.<\/p>\n<p>On the downside, when you add unrelated constructors to <code>Foo<\/code> (say more of type <code>Foo A<\/code>) you&#8217;ll have to add more cases to <code>errorFoo<\/code>, and that could be unfun (though easy and mechanical) if you&#8217;ve got lots of functions applying this pattern.<\/p>\n<p id=\"rop\"><small>Originally posted 2013-11-09 19:46:24. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>The problem actually reported is: Warning: Pattern match(es) are non-exhaustive In an equation for `fun&#8217;: Patterns not matched: Inl _ Which is true. You provide a case for the Inr constructor, but not the Inl constructor. What you&#8217;re hoping is that since there&#8217;s no way to provide a value of type Sig B that uses [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-496","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/496","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=496"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/496\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}