Annoying problem when pattern matching negative integer literals and wildcards

I have the following program: module Bug ( encryptionResult ) where data EncryptionResult = HasEncryption | EncryptionUnknown encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult -1 = EncryptionUnknown encryptionResult _ = error "Internal error." When I try to compile it with GHC I get [1 of 1] Compiling Bug ( Bug.hs, Bug.o ) Bug.hs:9:1: error: Multiple declarations of ‘encryptionResult’ Declared at: Bug.hs:7:1 Bug.hs:9:1 | 9 | encryptionResult _ = error "Internal error." | ^^^^^^^^^^^^^^^^ I can replicate this in Hugs, viz. ERROR "Bug.hs":7 - "encryptionResult" multiply defined However, everything compiles fine when I write module Bug ( encryptionResult ) where data EncryptionResult = HasEncryption | EncryptionUnknown encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult -1 = EncryptionUnknown or module Bug ( encryptionResult ) where data EncryptionResult = HasEncryption | EncryptionUnknown encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult 0 = EncryptionUnknown encryptionResult _ = error "Internal error." Am I doing something obviously screwy? This seems like a pretty annoying feature on the language (to the point where I assumed it was a GHC bug until I got the same behavior with Hugs) and I can't figure out why it exists. Cheers, Vanessa McHale

Ah nevermind, I figured it out: the second bit was being treated as a definition for (-) On 3/14/19 10:54 PM, Vanessa McHale wrote:
I have the following program:
module Bug ( encryptionResult ) where
data EncryptionResult = HasEncryption | EncryptionUnknown
encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult -1 = EncryptionUnknown encryptionResult _ = error "Internal error."
When I try to compile it with GHC I get
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
Bug.hs:9:1: error: Multiple declarations of ‘encryptionResult’ Declared at: Bug.hs:7:1 Bug.hs:9:1 | 9 | encryptionResult _ = error "Internal error." | ^^^^^^^^^^^^^^^^
I can replicate this in Hugs, viz.
ERROR "Bug.hs":7 - "encryptionResult" multiply defined
However, everything compiles fine when I write
module Bug ( encryptionResult ) where
data EncryptionResult = HasEncryption | EncryptionUnknown
encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult -1 = EncryptionUnknown
or
module Bug ( encryptionResult ) where
data EncryptionResult = HasEncryption | EncryptionUnknown
encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult 0 = EncryptionUnknown encryptionResult _ = error "Internal error."
Am I doing something obviously screwy? This seems like a pretty annoying feature on the language (to the point where I assumed it was a GHC bug until I got the same behavior with Hugs) and I can't figure out why it exists.
Cheers, Vanessa McHale

Maybe one of the numeric literal extensions will help. The root problem is
that, without parentheses or one of the extensions, this ends up defining
something different than you intended: (-) with `encryptionResult` as a
local binding.
On Thu, Mar 14, 2019 at 11:55 PM Vanessa McHale
I have the following program:
module Bug ( encryptionResult ) where
data EncryptionResult = HasEncryption | EncryptionUnknown
encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult -1 = EncryptionUnknown encryptionResult _ = error "Internal error."
When I try to compile it with GHC I get
[1 of 1] Compiling Bug ( Bug.hs, Bug.o )
Bug.hs:9:1: error: Multiple declarations of ‘encryptionResult’ Declared at: Bug.hs:7:1 Bug.hs:9:1 | 9 | encryptionResult _ = error "Internal error." | ^^^^^^^^^^^^^^^^
I can replicate this in Hugs, viz.
ERROR "Bug.hs":7 - "encryptionResult" multiply defined
However, everything compiles fine when I write
module Bug ( encryptionResult ) where
data EncryptionResult = HasEncryption | EncryptionUnknown
encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult -1 = EncryptionUnknown
or
module Bug ( encryptionResult ) where
data EncryptionResult = HasEncryption | EncryptionUnknown
encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult 0 = EncryptionUnknown encryptionResult _ = error "Internal error."
Am I doing something obviously screwy? This seems like a pretty annoying feature on the language (to the point where I assumed it was a GHC bug until I got the same behavior with Hugs) and I can't figure out why it exists.
Cheers, Vanessa McHale _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- brandon s allbery kf8nh allbery.b@gmail.com

On Thu, Mar 14, 2019 at 10:54:58PM -0500, Vanessa McHale wrote:
encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult -1 = EncryptionUnknown encryptionResult _ = error "Internal error."
The way I keep it straight, is that just as one must write: let x = encryptionResult (-1) to evaluate "encryptionResult" at (-1), one must also write: encryptionResult :: Int -> EncryptionResult encryptionResult 1 = HasEncryption encryptionResult (-1) = EncryptionUnknown encryptionResult _ = error "Internal error." to define the function, because binary minus takes precedence over unary minus (which in turn takes precedence over sections, thus (subtract 1), not (- 1)). -- Viktor.
participants (3)
-
Brandon Allbery
-
Vanessa McHale
-
Viktor Dukhovni