Consider the Haskell functions
test :: ST s [Int]
test = do
arr <- newListArray (0,9) [0..9] :: ST s (STArray s Int Int)
let f i = do writeArray arr i (2*i)
readArray arr i
forM [1,2] f
and
test' :: ST s [Int]
test' = do
arr <- newListArray (0,9) [0..9] :: ST s (STArray s Int Int)
let f = \i -> do writeArray arr i (2*i)
readArray arr i
forM [1,2] f
The first requires FlexibleContexts to compile on ghci 8.10.1, the second compiles with no extra options. Why?
An answer that explains this behaviour in terms of the scope of the type variable s
would be especially welcome. As a follow up, what (if any) type signature can be added to the function f
to make test
compile without FlexibleContexts? Finally, is there a connection with the monomorphism restriction?
You can check which type GHC assigns to
f
in GHCi:This is more general than the type you suggest in your comments and the reason that
FlexibleContexts
are needed.You can add the type signature you suggested (
Int -> ST s Int
) to avoid having to useFlexibleContexts
:Note that scoped type variables and the
forall s.
are necessary here because you need to make sure that thes
in all the type signatures refer to the same type variable and do not all introduce new type variables.The reason that the monomorphism restriction treats your first and your second version differently is because it doesn't apply to things that look like functions. In your first version
f
has an argument, so it looks like a function and therefore will get a general type. In your second versionf
doesn't have arguments, so it doesn't look like a function which means that the monomorphism restriction forces it to have a more specific type.