[Haskell-beginners] let in GHCI
Henry Lockyer
henry.lockyer at ntlworld.com
Sun Dec 11 20:11:00 CET 2011
That's most helpful Daniel. I see the root of the issue now.
Will digest.
Thanks/ Henry
On 11 Dec 2011, at 18:54, Daniel Fischer wrote:
> On Sunday 11 December 2011, 19:14:56, Henry Lockyer wrote:
>> Hello Haskellers
>>
>> Why is it that in GHCI I can do, for example,
>>
>>> let my6 = replicate 6
>>> my6 5
>>
>> [5,5,5,5,5,5]
>>
>> but if I do
>>
>>> sort "bav"
>>
>> "abv"
>>
>> this is ok, but
>>
>>> let mySort = sort
>
> It's the monomorphism restriction.
> If a value is bound by a simple pattern binding (let val = whatever)
> without a type signature, and if the inferred type is constrained by some
> class requirements, the value gets a monomorphic type, any constrained type
> variables are resolved according to the defaulting rules in
> http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-790004.3.4
>
> The first example has no constrained type variables,
>
> replicate :: Int -> a -> [a]
>
> so
>
> my6 :: a -> [a]
>
> is parametric, it works the same for all types. Therefore it remains
> polymorphic.
>
> But
>
> sort :: Ord a => [a] -> [a]
>
> has a constrained type variable, so a value bound like
>
> let mySort = sort
>
> gets a monomorphic type, the constrained type variable a is replaced with a
> fixed type according to defaulting rules.
>
> Since the defaulting rules in the linked section require one of the
> constraining classes to be a numeric class, that binding should be a static
> error by these rules.
>
> However, strict adherence to the defaulting rules would produce a *lot* of
> type errors at the ghci prompt, so ghci has extended defaulting rules,
> resolving more cases, for example, Show, Eq and Ord constraints (with no
> numeric constraint around) are satisfied by instantiating the constrained
> type variable with ().
>
> Thus the binding
>
>> let mySort = sort
>
> at the ghci prompt results in
>
>> :t mySort
> mySort :: [()] -> [()]
>
> You get the inferred (most general) type if you
>
> 1) bind the value with a function binding (one with at least one argument
> before the =),
>
>> let mySort xs = sort xs
>
> 2) give a polymorphic type signature
>
>> let mySort :: Ord a => [a] -> [a]; mySort = sort
>
> 3) disable the monomorphism restriction
>
>> :set -XNoMonomorphismRestriction
>> let mySort = sort
>
> It's often a good idea to disable the monomorphism restriction at the ghci
> prompt by default, so you might consider doing that in your .ghci file.
>
>
> If the monomorphism restriction so often leads to surprising and confusing
> results, why does it exist at all?
>
> Because without it, there'd be another surprising and unpleasant result.
> If you have something that looks like a constant,
>
> name = value
>
> you'd likely expect it to be evaluated only once. But if name got a
> polymorphic type, it would have to be re-evaluated for every use.
> To avoid the unpleasant surprise of bad performance due to re-evaluation,
> we have the monomorphism restriction.
>
> If you give it a polymorphic signature ore bind it via a function binding,
> it's obvious that the value isn't shared and has to be recalculated.
>
> Is that a sufficiently good reason to have the MR?
> Opinions differ.
More information about the Beginners
mailing list