Non-Overlapping Patterns

Hi isZero :: Int -> Bool isZero 0 = True isZero n | n /= 0 = False The order in which the above equations appear makes no difference to the application of isZero. Does the Haskell interpreter rewrite patterns into one single definition using some sort of switch or if construct? Why does an equation without a guard have to be placed after the more specific cases?To put it another way, why doesn't the interpreter identify the more specific cases and put them before the general ones. Cheers Paul

PR Stanley wrote:
To put it another way, why doesn't the interpreter identify the more specific cases and put them before the general ones.
I'm guessing because determining which equation is the "most general" is equivilent to the Halting Problem in the general case. (Notice that Mathematica does almost exactly the same thing: it has a few heuristics for figuring out what is more general, but beyond that it uses the order you specify.) As to how function application is actually implemented - well, that depends on what you're using to run your Haskell. ;-) I believe GHC uses pointer blocks rather than switch blocks (loosely speaking).

PR Stanley
Hi isZero :: Int -> Bool isZero 0 = True isZero n | n /= 0 = False
The order in which the above equations appear makes no difference to the application of isZero. Does the Haskell interpreter rewrite patterns into one single definition using some sort of switch or if construct? Why does an equation without a guard have to be placed after the more specific cases?To put it another way, why doesn't the interpreter identify the more specific cases and put them before the general ones. Cheers Paul
For completeness' sake: isZero 0 = True isZero _ = False works, and, contrary to your example, requires an order to have a well defined meaning. It's equivalent[1] to isZero n = case n of 0 -> True _ -> False , and yours to isZero n = case n of 0 -> True n -> if n /= 0 then False else undefined I'll leave the last question unanswered, just try to write such a beast. PS: I prefer isZero = (==) 0 [1] which doesn't mean that one is reduced to the other. It just means they're semantically identical. -- (c) this sig last receiving data processing entity. Inspect headers for past copyright information. All rights reserved. Unauthorised copying, hiring, renting, public performance and/or broadcasting of this signature prohibited.

Achim Schneider
isZero n = case n of 0 -> True n -> if n /= 0 then False else undefined
You can't exchange the order, here, of course, the semantics of this and a guard-version would differ. -- (c) this sig last receiving data processing entity. Inspect headers for past copyright information. All rights reserved. Unauthorised copying, hiring, renting, public performance and/or broadcasting of this signature prohibited.

PR Stanley
after the more specific cases?To put it another way, why doesn't the interpreter identify the more specific cases and put them before the general ones.
Given the function foo below, which of the first lines is more specific? No reordering means, that it is obvious that (foo 0 1) results in one. foo :: Int -> Int -> Bool foo x 1 = 1 foo 0 y = 0 foo x y = 2 Regards, Michael Karcher

PR Stanley wrote:
Hi isZero :: Int -> Bool isZero 0 = True isZero n | n /= 0 = False
The order in which the above equations appear makes no difference to the application of isZero. Does the Haskell interpreter rewrite patterns into one single definition using some sort of switch or if construct?
Something a bit like that.
Why does an equation without a guard have to be placed after the more specific cases?
It doesn't. You could write the above the other way around if you wished.
To put it another way, why doesn't the interpreter identify the more specific cases and put them before the general ones.
Because it general it's convenient to have overlapping cases, where the order matters, and be able to choose the order. Jules
participants (5)
-
Achim Schneider
-
Andrew Coppin
-
Jules Bean
-
PR Stanley
-
usenet@mkarcher.dialup.fu-berlin.de