A part of the issue here is that in Haskell one can define partial functions, i.e., functions which may fail on certain inputs. Examples are read
, head
, tail
. Non-exhaustive pattern matching is the common cause of this partiality, others including error
, undefined
, and infinite recursion (even if in this case you do not get a runtime error, obviously).
In particular, read
is a bit nasty since it requires you to ensure that the string can be parsed. This is usually harder than ensuring that a list is non empty, for instance. One should use a safer variant such as
readMaybe :: Read a => String -> Maybe a
main = do
print $ readMaybe "11" :: Maybe Int -- prints Just 11
print $ readMaybe "11" :: Maybe String -- prints Nothing
Another part of the issue is that polymorphic values (such as read "11"
) are actually functions in disguise, since they depend on the type at which they are evaluated, as seen in the example above. The monomorphism restriction is an attempt to make them behave more as non-functions: it forces the compiler to find a single type for all the uses of the polymorphic value. If this is possible, the polymorphic value is evaluated only at that type, and the result can be shared in all the uses. Otherwise, you get a type error, even if the code would have been typeable without the restriction.
For example, the following code
main = do
let x = readMaybe "11"
print $ x :: Maybe Int
print $ x :: Maybe Int
parses 11
once if the monomorphism restriction is on, and twice if it is off (unless the compiler is smart enough to do some optimization). By comparison,
main = do
let x = readMaybe "11"
print $ x :: Maybe Int
print $ x :: Maybe String
raises a compile-time type error if the monomorphism restriction is on, and compiles and runs just fine if it is off (printing "Just 11" and "Nothing").
So, there is no clear winner between enabling and disabling the restriction.