[Haskell] Re: Implicit type of numeric constants

Robert Stroud R.J.Stroud at ncl.ac.uk
Wed Sep 20 11:25:43 EDT 2006

Dear Arie,

Thank you for your answers to my questions - I'd spotted the section  
on ambiguous types and defaults in the language manual, but I hadn't  
appreciated that it might be applicable in this situation because I  
didn't know that show and read could be applied to (almost) all types.

However, I still think there's a bit of an inconsistency here. I  
understand that if k had the type "Num a => a", then the expression  
"show k" would be ambiguous, but unless I write that expression,  
there's no ambiguity...

So it seems to me that the type checker is being a bit too eager to  
prevent something that hasn't happened yet.

In contrast, in the case where I write "let k = 2 ...", the type  
checker seems happy to resolve the polymorphic type within the  
context of the let expression, and does what I expect.

So is the problem that the context is effectively unbounded when I  
load the definition from a file, and hence the type checker has to be  
very conservative about preventing the ambiguity?

I'm afraid I'm also still not clear about why 2 doesn't default to  
2::Integer in the same way that k defaults to k::Integer, but that's  
probably because I don't understand polymorphic types properly yet.

Thanks again,


On 20 Sep 2006, at 13:35, Arie Peterson wrote:

> Hi Robert,
>> I'm a newcomer to Haskell and I've been typing some simple
>> expressions into Hugs in an attempt to understand how the built-in
>> numeric types work . However, I'm puzzled by the following example:
>> k = 2
>> f :: Int -> Int -> Int
>> f x y = x * y
>> After loading a file containing this code into Hugs, if I type "f 2
>> 2" I get the value 4 as expected, but if I type "f k k" I get a type
>> error because the type of k is inferred to be Integer.
>> This seems like a violation of referential transparency to me - I
>> would expect the inferred type of k to be the same as the type of 2.
> This is caused by a mechanism called "defaulting". See section  
> 4.3.4 of
> the Haskell report:
> <http://haskell.org/onlinereport/decls.html#default-decls>.
> In this case, the type of 'k' is defaulted to 'Integer'.
> Basically, the problem this tries to solve is that if 'k' would  
> have type
> '(Num a) => a', then the expression 'show k' is ambiguous: the  
> compiler
> cannot decide what instance of 'Show' and 'Num' to use (and in this  
> case
> the string 'show k' actually depends on that choice: '2 :: Double'  
> would
> be shown as "2.0", '2 :: Integer' as "2".
> You absolutely right about this defaulting breaking referential  
> transparency.
>> However, if I type an apparently equivalent let expression into Hugs
>> directly, then I get the value 4 as expected
>> let k = 2 ; f :: Int -> Int -> Int ; f x y = x * y in f k k
>> Why is there a difference in behaviour?
> Here, there is no defaulting, 'k' has the polymorphic type you  
> expect, and
> the use of 'k' as an argument to the monomorphically typed 'f'  
> chooses the
> right instance of 'Num'.
>> For that matter, if the type of 2 is "Num a => a", which I understand
>> to mean "an arbitrary numeric type", why is it OK to pass 2 to a
>> function that expects an Int?
> Well, "an arbitrary numeric type" in the sense "something of any  
> numeric
> type you may wish to ask for" (the implicit quantifier for 'a' is
> universal, not existential). When using 'k', additional type  
> constraints
> (such as the monomorphic type of 'f') determine the choice of  
> instance.
> Greetings,
> Arie
> -- 
> Mr. Pelican Shit may be Willy.
>   ^
>  /e\
>  ---

More information about the Haskell mailing list