| Version: 981112
| OS: sun 2.5
| compiler: gcc
| configuration: --with-readline
| Expected behaviour:
| The following script should be a type error since String is
| not an instance of class Num
| Observed behaviour:
| the script works fine!
| Transcript:
| f :: Num [Char] => ([Char] -> [Char]) -> [Char]
| f i = show (i 1) ++ i "hej"
This is not a bug, but the expected behaviour. The type assigned to
f says "IF String is an instance of Num, THEN you can use f to map
a function of type (String -> String) to a String." It doesn't say
or require that String IS an instance of Num. In fact, if you had
said:
f :: ([Char] -> [Char]) -> [Char],
without defining an instance Num String, then you would have got an
error.
Even without the Num String instance, the definition of f could still
be of use, because it might be imported in another module where the
required instance was available.
In a different setting, suppose, for example that you wrote a module
containing the definition of a class:
class Number a where
plus :: a -> a -> a
zero :: a
and the definition of an auxiliary function:
sumList :: Number a => [a] -> a
sumList = foldr plus zero
Would you expect to reject this definition if the module didn't also
define at least one instance of the class? I don't think you would,
and I think the same reasoning applies to your example too.
Finally, if you find all this freedom and flexibility too much, then
you might want to use the next release of Hugs, which will provide a
Haskell 98 mode that adopts, amongst other things, a stricter approach
to context reduction.
All the best,
Mark