I have a test function like below which uses runST
to internally mutate state. I defined another function go
within it which returns Int
wrapped in ST
as result (just playing with some ST
concepts). The problem is that my type signature for the function seems to be wrong. If I comment out the function type signature, code runs fine. With type signature as in the commented code, it doesn't compile because the compiler interprets the state of the go
function as different from the state in enclosing scope. I will appreciate pointers on how to define the function type signature to pass outer ST s
to go
function.
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Data.Word(Word32)
import Data.Vector.Unboxed as U hiding (mapM_,create)
import Control.Monad.ST as ST
import Control.Monad.Primitive (PrimState)
import System.Random.MWC
test :: Word32 -> Int
test x = runST $ do
gen <- initialize (U.singleton $ fromIntegral x :: U.Vector Word32) :: (forall s. ST s (Gen (PrimState (ST s))))
let --go :: Int -> ST s Int
go x = do
v <- uniformR (1,x) gen
return v
i <- go 100
return i
This is the compiler error I get if I uncomment type signature go :: Int -> ST s Int
:
Couldn't match type `s1' with `s'
`s1' is a rigid type variable bound by
the type signature for go :: Int -> ST s1 Int at A.hs:12:16
`s' is a rigid type variable bound by
a type expected by the context: ST s Int at A.hs:10:10
Expected type: Gen (PrimState (ST s1))
Actual type: Gen s
In the second argument of `uniformR', namely `gen'
In a stmt of a 'do' block: v <- uniformR (1, x) gen
In the expression:
do { v <- uniformR (1, x) gen;
return v }