[Haskell-beginners] Question about List Type Constraint and Null
Daniel Fischer
daniel.is.fischer at googlemail.com
Sat Jan 22 20:49:53 CET 2011
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).
More information about the Beginners
mailing list