16
votes

So, I have a very simple function that take two parameters : the first is a hour (between 0 and 23) and the second one is a minute (between 0 and 59). This function return the hour plus one minute, and format the hour in a beautiful style. By example, hour 11 12 return 11 heures et 13 minutes. Sorry for the french format of the hour.

So, I use in this function the show function, and the parameters need to be a number, so I have the type declaration (Num a, Show a) => a -> a -> String. But, when I try the function, I got an error and GHC say to me to add the Eq type constraint, but I don't understand why I need the Eq type constraint in this case. There is the code (again, sorry for the french text used in the function, but I think that it's not very important if you don't understand the function name and the text) :

heure :: (Num a, Eq a, Show a) => a -> a -> String
heure 23 59 = "Minuit"
heure 12 m  = "Midi et " ++ show (m+1) ++ " minutes"
heure h 59  = show (h+1) ++ " heures"
heure h m   = show h ++ " heures et " ++ show (m+1) ++ " minutes"

So : if I don't use Eq, I have an error and when I use it my code is correct. Why?

Thank you for your explanations!

1
Matching a numeric, character, or string literal pattern k against a value v succeeds if v == k, where == is overloaded based on the type of the pattern. See Haskell 2010 Language Report 3.17.2 Informal Semantics of Pattern Matching - nymk
@nymk: Section 6.4 of the 2010 Report says "[t]he class Num of numeric types is a subclass of Eq, since all numbers may be compared for equality." But what's going on here is that recent versions of GHC don't do it: "The Num class no longer has Eq or Show superclasses. A number of other classes and functions have therefore gained explicit Eq or Show constraints, rather than relying on a Num constraint to provide them." - Luis Casillas

1 Answers

22
votes

You need the Eq constraint because you're checking whether h is equal to 23 or 12 and whether m is equal to 59. You're doing it using pattern matching, not ==, but pattern matching against numeric literals that way still requires Eq (unlike pattern matching against constructors).