
Hello. Given the following function definitions f 0 = True g False = True ghc infers the following types for the functions: f :: (Eq a, Num a) => a -> Bool g :: Bool -> Bool Why f has "Eq a" in the context in ts type, and g does not? As both are defined using a constant pattern, I expected none of them should require the type of the argument to be instance of Eq. Romildo

I believe that "f 0 = ..." is a guard and the guard is pattern matching on
the constructor. Despite the fact that you don't have an instance of "f _ =
....", the compiler needs an Eq instance to determine if it should run the
"f 0" version of the function.
Does that make sense? Hopefully someone with a better grasp of the topic
will fill in the details.
--Tim
On Tue, Apr 10, 2012 at 12:57 PM,
Hello.
Given the following function definitions
f 0 = True
g False = True
ghc infers the following types for the functions:
f :: (Eq a, Num a) => a -> Bool g :: Bool -> Bool
Why f has "Eq a" in the context in ts type, and g does not?
As both are defined using a constant pattern, I expected none of them should require the type of the argument to be instance of Eq.
Romildo
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Tue, Apr 10, 2012 at 02:16:15PM -0700, Tim Perry wrote:
I believe that "f 0 = ..." is a guard and the guard is pattern matching on the constructor. Despite the fact that you don't have an instance of "f _ = ....", the compiler needs an Eq instance to determine if it should run the "f 0" version of the function.
Does that make sense? Hopefully someone with a better grasp of the topic will fill in the details.
I think you are using the wrong terms. The given examples does not make any use of guards. Guards are boolean expressions attached to the right side of equations. They are used to select one from many possible right sides of the equation: the first one whose guard evaluates to True is chosen. (Of course the patterns used as formal parameters should first match the actual arguments.) For instance sign x | x < 0 = -1 | x == 0 = 0 | x > 0 = 1 defines a function using an equation with three guards. I think pattern matching with constant data construtors is not related to the (==) or (/=) methods defined in class Eq. At least I was not able to find that out on the documentation. For this reason I am not understand why Eq is used when pattern matching with numeric constants, as shown in the original post. So, Tim's explanation is not making sense to me. ] Romildo
On Tue, Apr 10, 2012 at 12:57 PM,
wrote: Given the following function definitions
f 0 = True
g False = True
ghc infers the following types for the functions:
f :: (Eq a, Num a) => a -> Bool g :: Bool -> Bool
Why f has "Eq a" in the context in ts type, and g does not?
As both are defined using a constant pattern, I expected none of them should require the type of the argument to be instance of Eq.

On Tue, Apr 10, 2012 at 20:53,
I believe that "f 0 = ..." is a guard and the guard is pattern matching on the constructor. Despite the fact that you don't have an instance of "f _ = ....", the compiler needs an Eq instance to determine if it should run
On Tue, Apr 10, 2012 at 02:16:15PM -0700, Tim Perry wrote: the
"f 0" version of the function.
Does that make sense? Hopefully someone with a better grasp of the topic will fill in the details.
I think you are using the wrong terms. The given examples does not make any use of guards. Guards are boolean expressions attached to the right
It is using guards; you don't see them, because it's quietly translated by the compiler in the same way that `do` blocks are translated into applications of (>>=) and (>>) operators. The reason for this is that numeric literals aren't actually literals; they are applications of the `fromInteger` function. This is true even in patterns; therefore they can't actually be matched as patterns but are translated into guards. -- brandon s allbery allbery.b@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms

On Tue, 10 Apr 2012 16:57:38 -0300 j.romildo@gmail.com wrote:
Hello.
Given the following function definitions
f 0 = True
g False = True
ghc infers the following types for the functions:
f :: (Eq a, Num a) => a -> Bool g :: Bool -> Bool
Why f has "Eq a" in the context in ts type, and g does not?
Bool is an instance of Eq, so there's no need to say that your
(non-existent) type variable has that constraint.
Using a numeric constants means you get a type variable with the Num
constraint. Since Num doesn't imply Eq, that constraint is (as Tim
pointed out) required so the guard can be checked.

On Tue, Apr 10, 2012 at 05:30:37PM -0400, Mike Meyer wrote:
On Tue, 10 Apr 2012 16:57:38 -0300 j.romildo@gmail.com wrote:
Hello.
Given the following function definitions
f 0 = True
g False = True
ghc infers the following types for the functions:
f :: (Eq a, Num a) => a -> Bool g :: Bool -> Bool
Why f has "Eq a" in the context in ts type, and g does not?
Bool is an instance of Eq, so there's no need to say that your (non-existent) type variable has that constraint.
This is not really the reason; no instance of Eq for Bool is required. Note that you can even pattern-match like this on a type which is not an instance of Eq: data Foo = Bar | Baz f Bar = True Here the type of f is inferred as Foo -> Bool, even though there is no instance of Eq for Foo. Pattern-matching is more fundamental than equality testing. The reason Eq is needed for the definition f 0 = True is that 0 is not actually a constructor. Numeric literal patterns are provided as a convenience, but they desugar into a guard of the form f x | x == 0 = ... Hence, an instance of Eq is needed. -Brent

On Tue, Apr 10, 2012 at 05:30:37PM -0400, Mike Meyer wrote:
On Tue, 10 Apr 2012 16:57:38 -0300 j.romildo@gmail.com wrote:
Hello.
Given the following function definitions
f 0 = True
g False = True
ghc infers the following types for the functions:
f :: (Eq a, Num a) => a -> Bool g :: Bool -> Bool
Why f has "Eq a" in the context in ts type, and g does not?
Bool is an instance of Eq, so there's no need to say that your (non-existent) type variable has that constraint.
Using a numeric constants means you get a type variable with the Num constraint. Since Num doesn't imply Eq, that constraint is (as Tim pointed out) required so the guard can be checked.
Then consider the following type and function definitions: data T = A | B h A = True h B = False The type T is not an instance of Eq. The inferred type by ghc for the function h is h :: T -> Bool which does not require T to be an instance of the Eq class. Therefore pattern matching on the constant data constuctors A and B is not related to the Eq class, which provides the equality function (==). This example contradicts the explanation given above by Mike. And the question remains: why pattern matching on numeric constants, differently from other constants, requires the Eq class? Romildo
participants (5)
-
Brandon Allbery
-
Brent Yorgey
-
j.romildo@gmail.com
-
Mike Meyer
-
Tim Perry