[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