
At Sat, 2 Jul 2011 17:23:50 -0400, Brent Yorgey wrote:
On Sat, Jul 02, 2011 at 09:02:13PM +0200, Daniel Fischer wrote:
- disabling the monomorphism restriction :set -XNoMonomorphismRestriction let g = f
This is the recommended solution. The confusion caused by the MR far outweighs its occasional benefits.
Recommended by some people, but by no means everyone. For instance, Vytiniotis, Peyton Jones, and Schrijvers make a good argument that the monomorphism restriction should effectively be expanded to include both pattern and function bindings in let and where clauses: http://research.microsoft.com/pubs/102483/tldi10-vytiniotis.pdf The above paper is currently implemented in GHC, and on by default if you enable GADTs. (So you would additionally need -XNoMonoLocalBindings if you wanted to use GADTs.) Moreover, even with -XNoMonoLocalBindings, you still run into the fact that bindings are not generalized within a declaration group, which could lead to confusion. In particular, consider the following program: {-# LANGUAGE NoMonomorphismRestriction #-} x = 2 -- The type of x is: Num a => a y = (x + y) :: Int The type of x is what you would expect without the monomorphism restriction. Now say x has a gratuitous use of y: {-# LANGUAGE NoMonomorphismRestriction #-} x = 2 where _ = y -- The type of x is: Int y = (x + y) :: Int If you want x to be polymorphic in this case, you have to give it a type signature anyway: {-# LANGUAGE NoMonomorphismRestriction #-} x :: Num a => a x = 2 where _ = y y = (x + y) :: Int Thus, what I would recommend, instead of -XNoMonoLocalBindings, is to give type signatures to your polymorphic bindings. This makes the code more readable. It has the disadvantage that Haskell doesn't allow you to name monomorphic type variables, which, for local bindings, can require either the use of -XScopedTypeVariables or giving extra function arguments whose only purpose is to bring a type variable into scope. But both of those are probably more future-proof than -XNoMonomorphismRestriction. David