Does the GHC reject ST monad code as being unable to combine type variables?

I wrote the following function:

(.>=.) :: Num a => STRef sa -> a -> Bool r .>=. x = runST $ do v <- readSTRef r return $ v >= x 

but when I tried to compile, I got the following error:

 Could not deduce (s ~ s1) from the context (Num a) bound by the type signature for .>=. :: Num a => STRef sa -> a -> Bool at test.hs:(27,1)-(29,16) `s' is a rigid type variable bound by the type signature for .>=. :: Num a => STRef sa -> a -> Bool at test.hs:27:1 `s1' is a rigid type variable bound by a type expected by the context: ST s1 Bool at test.hs:27:12 Expected type: STRef s1 a Actual type: STRef sa In the first argument of `readSTRef', namely `r' In a stmt of a 'do' expression: v <- readSTRef r 

Can anyone help?

+7
source share
2 answers

This is exactly as intended. STRef is valid in only one runST run. And you are trying to put an external STRef in a new runST run. This is not true. This will allow arbitrary side effects in clean code.

So what you are trying to achieve is impossible. By design!

+12
source

You need to stay in the context of ST :

 (.>=.) :: Ord a => STRef sa -> a -> ST s Bool r .>=. x = do v <- readSTRef r return $ v >= x 

(And as the hammar points out, to use >= you will need an Ord typeclass, which Num does not provide.)

+7
source

All Articles