Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Pattern Matching Fails on Negative Number

The Haskell compiler throws an error on the following function:

balancedMax :: Int -> Int -> Int
balancedMax -1 _ = -1
balancedMax _ -1 = -1
balancedMax a b = max a b

Flipping the sign solves the problem:

balancedMax :: Int -> Int -> Int
balancedMax 1 _ = -1
balancedMax _ 1 = -1
balancedMax a b = max a b

Why does pattern matching fail on the negatives, and what is a clean workaround?

like image 473
Arion Avatar asked Jun 07 '13 05:06

Arion


People also ask

How do you write negative numbers in Haskell?

Negative literals. Enable negative numeric literals. The literal -123 is, according to Haskell98 and Haskell 2010, two tokens, a unary minus ( - ) and the number 123, and is desugared as negate (fromInteger 123) .

How does pattern matching work in Haskell?

Pattern matching consists of specifying patterns to which some data should conform and then checking to see if it does and deconstructing the data according to those patterns. When defining functions, you can define separate function bodies for different patterns.

Why ++ is not allowed in pattern matching?

You can only pattern-match on data constructors, and ++ is a function, not a data constructor. Data constructors are persistent; a value like 'c':[] cannot be simplified further, because it is a fundamental value of type [Char] .


2 Answers

It fails because it thinks you're trying to re-define the minus operator, because f -1 = ... gets parsed as f - 1 = ....

To fix this you just have to add parentheses:

balancedMax :: Int -> Int -> Int
balancedMax (-1) _ = -1
balancedMax _ (-1) = -1
balancedMax a b = max a b

The same thing happens in expressions. To call balancedMax with a negative literal, you would need parentheses as well.

like image 85
hammar Avatar answered Oct 23 '22 14:10

hammar


because f -1 = ... gets parsed as f - 1 = ....

Which if you don't know, means the same thing as:

(-) f 1 = ....

which is similar to defining a function like this:

somefunc x 1 = x + 1

Which happens to be equivalent to defining somefunc() like this:

x `somefunc` 1 = x + 1

It's just that with (-) you don't have to write the backticks when using it in infix position, i.e. positioned between its two arguments.

The two beginning haskell books I've looked at both warn you early on that the unary - needs to be used with parentheses, e.g. (-3).

like image 7
7stud Avatar answered Oct 23 '22 14:10

7stud