[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,
Robert
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