
On Saturday 22 January 2011 20:01:19, aditya siram wrote:
Yes that was a mistake, but the weirder thing is that fixing the type sig does nothing to change the behavior described before: it still fails to compile with -XNoMonomorphismRestriction and compiles fine if it's removed.
It's going to take me a while understand absorb your explanation.
Perhaps the following will help understanding it: module ReadStuff where test :: String -> Maybe Int test s = if null res then Nothing else Just $ fst $ head res where res = reads s Prelude> :l ReadStuff [1 of 1] Compiling ReadStuff ( ReadStuff.hs, interpreted ) ReadStuff.hs:4:18: Ambiguous type variable `a' in the constraint: (Read a) arising from a use of `res' Probable fix: add a type signature that fixes these type variable(s) In the first argument of `null', namely `res' In the expression: null res In the expression: if null res then Nothing else Just $ fst $ head res Failed, modules loaded: none. The inferred type for res is res :: Read a => [(a,String)] with an implicit (forall a.). The value of `null res' for a given String obviously depends on the type at which res is used. To make test work, the type of res to use there has to be determined somehow. The natural way is to force res in line 4 to have the same type as res in line 7, where the type is determined by the signature of test (you could also write `null (res :: [(Bool,String)])' in line 4, but that would lead to *** Exception: Prelude.head: empty list for some inputs). Turning the monomorphism restriction off says explicitly 'let res be a polymorphic value', so you get the ambiguous type variable in line 4. The monomorphism restriction says 'don't generalise the type of res [there's no type signature on res, so it's in a restricted binding group]'. So you get `res :: Read b => [(b,String)]' for some so far unknown, but monomorphic b. The use of res in line 7 determines b (here Int, in general the same type that instantiates the `a' in test's signature).