Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The problem actually reported is:</p> <pre><code>Warning: Pattern match(es) are non-exhaustive In an equation for `fun': Patterns not matched: Inl _ </code></pre> <p>Which is true. You provide a case for the <code>Inr</code> constructor, but not the <code>Inl</code> constructor.</p> <p>What you're hoping is that since there'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't need to handle the <code>Inl</code> constructor.</p> <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's what ghc is warning about.</p> <p>So to fix that you need to change <code>fun</code> to something like this:</p> <pre><code>fun :: Sig B -&gt; Int fun (Inr Bar) = 1 fun (Inl foo) = error "whoops" </code></pre> <p>But now of course if you later add <code>Baz :: Foo B</code> this function is a time bomb waiting to happen. It'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't write a pattern for bottom.</p> <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'll get a warning if you later add one. Something like this:</p> <pre><code>fun :: Sig B -&gt; Int fun (Inr Bar) = 1 fun (Inl foo) = errorFoo foo where errorFoo :: Foo a -&gt; b errorFoo Foo = error "whoops" </code></pre> <p>Now You've properly handled all the constructors of <code>:+:</code> in <code>fun</code>, the "impossible" 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's defined in an attached <code>where</code>.</p> <p>On the downside, when you add unrelated constructors to <code>Foo</code> (say more of type <code>Foo A</code>) you'll have to add more cases to <code>errorFoo</code>, and that could be unfun (though easy and mechanical) if you've got lots of functions applying this pattern.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload