I'm really at a loss to explain why this is a type error:
foo :: (Eq a) => a -> a
foo _ = 2
Can anyone explain?
I'm really at a loss to explain why this is a type error:
foo :: (Eq a) => a -> a
foo _ = 2
Can anyone explain?
Because the type of
foo "bar"
should be String, according to your signature, but is not (2 is not a String). In your code foo is generic, so it should return an instance of exactly the same type as the argument.
The power of haskell type system gives us additional information - all you can do with the argument inside foo is to check for its equality with something else, but as I can come up with any new type (lets call it Baz) and use foo on it - you can't possibly have any other instances of Baz, so the only way to return an instance of Baz is to return the exact same instance as the argument.
If you rewrote foo like so:
foo _ = True
it would have a signature of foo :: a -> Bool
, this is basically what you tried to do, but things get more complicated with numbers.
In general your function has a signature
foo :: (Num t1) => t -> t1
which means that it returns a Num instance for any given argument. (This is because 2 can have many different types in haskell, depending on what you need it can be an Int or a Real or other.)
You should play around with types in ghci, for example:
:t foo
will give you the infered type signature for foo.
:t 2
gives you (Num t) => t
which means that 2 can be an instance of any type which implements Num.
The type signature which you declared means
for all types
a
(which instantiate Eq),foo
takes a value of this type and returns another value of this type
You can even directly write it this way:
foo :: forall a . Eq a => a -> a
Now the function definition
foo _ = 2
says something different:
Regardless of what type is given, return a number.
And of course this types are incompatible.
Example: As Michał stated, since foo "Hello"
is given a String
, it should return a string, but actually does return a number.