Prelude> func f = [(show s, f == s) | s <- [0, 1..10]]
Prelude> :type func
func :: (Num a, Enum a, Show a, Eq a) => a -> [(String, Bool)]
I would expect f
to just be an instance of Eq a
but all the class constraints applied to s
are also applied to f
for some reason. Replacing s
with any constant removes the relevant type constraint for f
, and replacing s
in the equality removes all class constraints except Eq a
for f
.
Can someone explain to me why does the type of local variables that are values affect the type of input variables that are values?
Their sole purpose is to label and store data in memory.
Advantages of using local variables: We do not have to take care of deleting unnecessary variables when the task is complete because local variables are deleted from memory automatically when their task is complete. When you use local variables, you do not have to worry that they will be changed by another task.
Functions can access global variables and modify them. Modifying global variables in a function is considered poor programming practice. It is better to send a variable in as a parameter (or have it be returned in the 'return' statement).
Variable length argument is a feature that allows a function to receive any number of arguments.
Eq
doesn't exist in a vacuum. To compare two things for equality, you have to have two things. And, crucially, those two things have to be of the same type. In Haskell, 0 == "A"
isn't just false; it's a type error. It literally doesn't make sense.
f == s
When the compiler sees this, even if it knows nothing else about the types of f
and s
, it knows what (==)
is. (==)
is a function with the following signature.
(==) :: Eq a => a -> a -> Bool
Both arguments are of the same type. So now and forevermore, for the rest of type-checking this expression, we must have f
and s
of the same type. Anything required of s
is also required of f
. And s
takes values from [0, 1..10]
. Your type constraints come as follows
Num
is required since s
takes values from a list of literal integers.Enum
is required by the [..]
list enumeration syntax.Show
is required by show s
.Eq
is required by the f == s
equality expression.Now, if we replace s
with a constant, we get something like
func f = [(show s, f == 0) | s <- [0, 1..10]]
Now f
is being compared with 0
. It has no relation to s
. f
requires Eq
(for (==)
) and Num
(since we're comparing against zero, a number). s
, on the other hand, requires Enum
, Num
, Eq
, and Show
. In the abstract, this should actually be a type error, since we've given no indication as to which type s
should be and there aren't enough clues to figure it out. But type defaulting kicks in and we'll get Integer
out of it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With