is monomorphism restriction necessary?

Sorry for the question that probably is already answered somewhere, but i do not get it from the basic documentation i have looked at so far. Is monomorphism restriction really necessary, or is it just a convenience? In the example from A History of Haskell genericLength :: Num a => [b] -> a f xs = (len, len) where len = genericLength xs can't the monomorphism restriction be replaced with just adding the signature f :: Num a => [b] -> (a, a) ? If yes, are there other cases where there is no way to get the desired behavior without enabling the monomorphism restriction? Alexey.

On 04/16/2016 02:53 PM, Alexey Muranov wrote:
Sorry for the question that probably is already answered somewhere, but i do not get it from the basic documentation i have looked at so far.
Is monomorphism restriction really necessary, or is it just a convenience?
In the example from A History of Haskell
genericLength :: Num a => [b] -> a
f xs = (len, len) where len = genericLength xs
can't the monomorphism restriction be replaced with just adding the signature
f :: Num a => [b] -> (a, a)
?
No; the let binding 'len' would still generalize. It would generalize even if you assigned 'f' a monotype such as [b] -> (Int, Int). Now, the compiler *could* later realize that the polymorphic value 'len' is evaluated twice at the same type and perform a CSE, but I guess the standard authors were not comfortable with *requiring* that kind of optimization from all compliant compilers. Of course, nowadays we have scoped type variables, so MR is no longer strictly necessary. Sometimes it is desirable in that it gives the behavior that you would intuitively expect; sometimes, the opposite. Roman

On Saturday, April 16, 2016 at 5:49:24 PM UTC+2, Roman Cheplyaka wrote:
On 04/16/2016 02:53 PM, Alexey Muranov wrote:
Sorry for the question that probably is already answered somewhere, but i do not get it from the basic documentation i have looked at so far.
Is monomorphism restriction really necessary, or is it just a convenience?
In the example from A History of Haskell
genericLength :: Num a => [b] -> a
f xs = (len, len) where len = genericLength xs
can't the monomorphism restriction be replaced with just adding the signature
f :: Num a => [b] -> (a, a)
?
No; the let binding 'len' would still generalize. It would generalize even if you assigned 'f' a monotype such as [b] -> (Int, Int).
Now, the compiler *could* later realize that the polymorphic value 'len' is evaluated twice at the same type and perform a CSE, but I guess the standard authors were not comfortable with *requiring* that kind of optimization from all compliant compilers.
Of course, nowadays we have scoped type variables, so MR is no longer strictly necessary. Sometimes it is desirable in that it gives the behavior that you would intuitively expect; sometimes, the opposite.
Roman
Thank you, i will think about it, though i don't understand yet. Could you show me, please, how to use scoped type variables to avoid MR in this example? Alexey.

On 04/16/2016 10:22 PM, Alexey Muranov wrote:
Could you show me, please, how to use scoped type variables to avoid MR in this example?
All MR does is it prevents a binding from being generalized. Another way to achieve that would be to give that binding a (monomorphic) type signature. Without scoped t.v., you can't give a signature to 'len' while keeping 'f' polymorphic in the return type. With scoped t.v., you can: f :: forall a b . Num a => [b] -> (a,a) f xs = (len, len) where len :: a len = genericLength xs Roman

On Saturday, April 16, 2016 at 10:10:37 PM UTC+2, Roman Cheplyaka wrote:
On 04/16/2016 10:22 PM, Alexey Muranov wrote:
Could you show me, please, how to use scoped type variables to avoid MR in this example?
All MR does is it prevents a binding from being generalized. Another way to achieve that would be to give that binding a (monomorphic) type signature. Without scoped t.v., you can't give a signature to 'len' while keeping 'f' polymorphic in the return type. With scoped t.v., you can:
f :: forall a b . Num a => [b] -> (a,a) f xs = (len, len) where len :: a len = genericLength xs
Great, thanks for the explanation (i'll think about it). If i have understood correctly, having scoped type variables, MR is no longer needed at all then. Alexey.
participants (2)
-
Alexey Muranov
-
Roman Cheplyaka