[Haskell-beginners] why is the :type different in ghci?
Antoine Latter
aslatter at gmail.com
Tue Aug 23 16:49:17 CEST 2011
On Tue, Aug 23, 2011 at 2:36 AM, Ovidiu Deac <ovidiudeac at gmail.com> wrote:
> Thanks for the explanation.
>
> I kind of understand what you mean but I don't understand why would
> anybody want this functionality.
>
The concerns is that if you write:
> x = <long complex computation>
and then the compiler generalizes the type to be polymorphic, what you
were expecting to only be computed once is instead computed repeatedly
- we can't save off the value to the top level at runtime if the value
at the top level doesn't have a fixed type!
This is why if you write a polymorphic type signature:
> x :: Num a => a
> x = <long complex computation>
the compiler assumes that know what you're doing.
Antoine
>
> On Tue, Aug 23, 2011 at 7:04 AM, Brandon Allbery <allbery.b at gmail.com> wrote:
>> On Mon, Aug 22, 2011 at 23:26, Ovidiu Deac <ovidiudeac at gmail.com> wrote:
>>>
>>> Prelude> :type map show
>>> map show :: Show a => [a] -> [String]
>>> Prelude> map show [1,2,3]
>>> ["1","2","3"]
>>> Prelude> let f = map show
>>> Prelude> :type f
>>> f :: [()] -> [String]
>>
>> Ah, another victim of the MMR and extended defaulting....
>> Very briefly, the Haskell spec says that a binding without arguments is
>> monomorphic, i.e. must have a single specific type. Your "let f =" is such
>> a binding.
>> Extended defaulting is how ghci gets itself out of that situation: it looks
>> for a type in the list of default types which can be used to build a
>> concrete type. Under standard defaulting rules it would fail, since the
>> default types are Double and Integer and the result would be an inability to
>> pick one; under extended defaulting, () is added and breaks the deadlock.
>> So you get a defaulted monomorphic type ([()] -> [String]).
>> If you disable the monomorphism restriction, you will get the most general
>> type which is the same as you got for ":t map show". You can also
>> explicitly type f:
>>> let f :: Show a => [a] -> String; f = map show
>>>
>>> <interactive>:1:8:
>>> No instance for (Num ())
>>> arising from the literal `3'
>>> Possible fix: add an instance declaration for (Num ())
>>> In the expression: 3
>>> In the first argument of `f', namely `[1, 2, 3]'
>>> In the expression: f [1, 2, 3]
>>
>> And this lovely bizarro-land error is because the Haskell spec causes
>> numeric literals to be translated to applications of fromInteger (so you
>> don't have to explicitly specify whether it's Int, Integer, Double, Word16,
>> etc.), so ghci tries to resolve
>>> f [fromIntegral 1, fromIntegral 2, fromIntegral 3] :: [()] -> [String]
>> in which fromIntegral must be (Integral a => a -> ()), but can't find a
>> fromIntegral instance that produces a ().
>> Common wisdom these days is to disable the monomorphism restriction when
>> working with ghci; there's a growing belief that it has outlived its
>> usefulness.
>>> :set -XNoMonomorphismRestriction
>> --
>> brandon s allbery allbery.b at gmail.com
>> wandering unix systems administrator (available) (412) 475-9364 vm/sms
>>
>>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
More information about the Beginners
mailing list