On Tue, Feb 10, 2015 at 11:14 PM, Frerich Raabe <raabe@froglogic.com> wrote:
Interesting! This got me thinking - is this issue because the compiler doesn't (cannot?) see the implementation of e.g. (<=)?


It "sees" the implementation of (<=) for otherwise it won't be able to generate code for it. But see below.
 
I noticed that a similiar case exists with

  f :: Bool -> Bool
  f x | x = True
      | not x = False

...which yields the same warning. I suppose this is because the compiler doesn't know the definition of 'not' so it doesn't understand that either of the two guards will always be True.

Again, it has to "know" the definition of the function "not" because it has to generate code to call it.

But it doesn't "know" the function from any other function, say foo. Semantically speaking, both are equally opaque.

Now you could point out that "Ah, but look at the definition of not. It could inline, simplify, et voila, obtain

f True = True
f False = False

and hence pattern-matching is complete."

Therein lies the rub. All that inlining and simplification boils down to evaluating the program _in_ the compiler, so if your program diverges so would the compiler, which wouldn't be a happy thing.



-- Kim-Ee