
Hello Haskellers Why is it that in GHCI I can do, for example,
replicate 6 5 [5,5,5,5,5,5] 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 mySort "bav"
<interactive>:1:8: Couldn't match expected type `()' with actual type `Char' Expected type: [()] Actual type: [Char] In the first argument of `mySort', namely `"bav"' In the expression: mySort "bav" and/or
mySort [6,5,9]
<interactive>:1:13: No instance for (Num ()) arising from the literal `9' Possible fix: add an instance declaration for (Num ()) In the expression: 9 In the first argument of `mySort', namely `[6, 5, 9]' In the expression: mySort [6, 5, 9] This is eluding me at the moment..! ;-) / Henry

I don't understand it perse, but I've run into it often enough to say
that the problem is the monomorphism restriction. When you say let
mySort = sort, instead of having the type
mySort :: Ord a => [a] -> [a]
which is what you'd expect, instead there is some bizarre rule in the
haskell spec that says it has to choose () for a in this case so if
you look at the type after you define it in ghci, you'll see the type
is actually
mySort :: [()] -> [()]
which is completely useless for anything. If you go :set
-XNoMonomorphismRestriction in ghci, you'll get the correct type and
it will work the way you intend. There is apparently some obscure
case where this is desirable and that is the only reason it has not
been removed by default.
On Sun, Dec 11, 2011 at 1:14 PM, Henry Lockyer
Hello Haskellers
Why is it that in GHCI I can do, for example,
replicate 6 5 [5,5,5,5,5,5] 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 mySort "bav"
<interactive>:1:8: Couldn't match expected type `()' with actual type `Char' Expected type: [()] Actual type: [Char] In the first argument of `mySort', namely `"bav"' In the expression: mySort "bav"
and/or
mySort [6,5,9]
<interactive>:1:13: No instance for (Num ()) arising from the literal `9' Possible fix: add an instance declaration for (Num ()) In the expression: 9 In the first argument of `mySort', namely `[6, 5, 9]' In the expression: mySort [6, 5, 9]
This is eluding me at the moment..! ;-)
/ Henry
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Thanks a lot David - that looks like it. Searched 'monomorphism' and found some material in the Haskell wiki to read. Wasn't galloping senility at least, in this case.. Cheers/ Henry On 11 Dec 2011, at 18:36, David McBride wrote:
I don't understand it perse, but I've run into it often enough to say that the problem is the monomorphism restriction. When you say let mySort = sort, instead of having the type
mySort :: Ord a => [a] -> [a]
which is what you'd expect, instead there is some bizarre rule in the haskell spec that says it has to choose () for a in this case so if you look at the type after you define it in ghci, you'll see the type is actually
mySort :: [()] -> [()]
which is completely useless for anything. If you go :set -XNoMonomorphismRestriction in ghci, you'll get the correct type and it will work the way you intend. There is apparently some obscure case where this is desirable and that is the only reason it has not been removed by default.
On Sun, Dec 11, 2011 at 1:14 PM, Henry Lockyer
wrote: Hello Haskellers
Why is it that in GHCI I can do, for example,
replicate 6 5 [5,5,5,5,5,5] 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 mySort "bav"
<interactive>:1:8: Couldn't match expected type `()' with actual type `Char' Expected type: [()] Actual type: [Char] In the first argument of `mySort', namely `"bav"' In the expression: mySort "bav"
and/or
mySort [6,5,9]
<interactive>:1:13: No instance for (Num ()) arising from the literal `9' Possible fix: add an instance declaration for (Num ()) In the expression: 9 In the first argument of `mySort', namely `[6, 5, 9]' In the expression: mySort [6, 5, 9]
This is eluding me at the moment..! ;-)
/ Henry
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

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... 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.

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...
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.
participants (3)
-
Daniel Fischer
-
David McBride
-
Henry Lockyer