Closely related to my most recent question on handling large data blocks, I have reached the point in which I need to take a large immutable data block, make it mutable for some operations, and then make it immutable again when I am done.
Since I want to retain at least the appearance of purity, the mutable data will be a mutable copy of the original immutable data. For reference, I'm looking at the Bloom Filter example in Real World Haskell, but finding that I cannot actually make my code run in runST.
My data structures, first the pure one, then the impure:
import Data.Vector.Unboxed (Vector)
import Data.Vector.Unboxed.Mutable (MVector)
data PixelMap = Bitmap Int Int (Vector Bool)
data MPixelMap s = MBitmap Int Int (MVector s Bool)
And then I create just a basic newBitmapM function:
newBitmapM :: (Int, Int) -> ST s (MPixelMap s)
newBitmapM (width, height) = MBitmap width height `liftM` MV.replicate (width * height) False
This loads into GHCI just fine, but then I try to run it:
> runST $ newBitmapM (15, 15)
<interactive>:78:9:
Couldn't match type `a' with `PixelMapMutable s'
`a' is a rigid type variable bound by
the inferred type of it :: a at <interactive>:78:1
Expected type: ST s a
Actual type: ST s (PixelMapMutable s)
In the return type of a call of `newBitmapM'
In the second argument of `($)', namely `newBitmapM (15, 15)'
In the expression: runST $ newBitmapM (15, 15)
This error message makes no sense to me at all. a
, defined in the type for runST
should be polymorphic, and thus not at all "fixed". Can anyone decode this enough to tell me what is really wrong with the code?