Lennart Augustsson lennart at augustsson.net
Thu Oct 8 06:48:46 EDT 2009

```The reason a gets a single type is the monomorphism restriction (read
the report).
Using NoMonomorphismRestriction your example with a works fine.

On Thu, Oct 8, 2009 at 12:29 PM, Cristiano Paris <frodo at theshire.org> wrote:
> On Thu, Oct 8, 2009 at 11:04 AM, minh thu <noteed at gmail.com> wrote:
>> Hi,
>>
>> I'd like to know what are the typing rules used in Haskell (98 is ok).
>>
>> Specifically, I'd like to know what makes
>>
>> let i = \x -> x in (i True, i 1)
>>
>> legal, and not
>>
>> let a = 1 in (a + (1 :: Int), a + (1.0 :: Float))
>>
>> Is it correct that polymorphic functions can be used polymorphically
>> (in multiple places) while non-functions receive a monomorphic type ?
>
> First, "1" IS a constant function so it's in no way special and is a
> value like any other.
>
> That said, the type of 1 is (Num t) => t, hence polymorphic. But, when
> used in the first element of the tuple, a is assigned a more concrete
> type (Int) which mismatches with the second element of the tuple,
> which is a Float.
>
> If you swap the tuple, you'll find that the error reported by ghci is
> the very same as before, except that the two types are swapped.
>
> Is it possible to rewrite the expression so as to work? The answer is
> yes, using existential quantification (and Rank2 polymorphism).
>
> Here you are:
> {-# LANGUAGE ExistentialQuantification, Rank2Types #-}
> foo :: (forall a. (Num a) => a) -> (Int,Float)
> foo = \x -> (x + (1 :: Int), x + (1 :: Float))
>
> Hence:
>
> foo 1 --> (2,2.0)
>
> Bye,
>
> Cristiano
> _______________________________________________