Is there a (low-level) GHC feature which will allow an in-place update of a particular constructor/record field in an IORef
, for efficiency?
Given the following code:
data Object = Object {
field1 :: Int
field2 :: VeryLargeDataType
}
main :: IO ()
main = do
var <- newIORef
writeIORef var $ Object {
field1 = 42,
field2 = lotsOfData
}
modifyIORef var (\a -> a { field1 = (field1 a + 1) } )
...
GHC will read out the very large object, perform the trivial modification, and write it back.
In theory, an in-place update of just the field would be sufficient, and far more efficient.
Is there any GHC feature, e.g. a low-level primitive, that would allow me to do this for any ADT?
I know the special-case solution is to make ther fields IORef
s rather than the structure, but I'm looking for a way to do this with any structure, including from a library.
There is no such feature. It is also not safe in general: modifying that large object in-place means that anybody that read from the reference before will now have a different value than they used to. (There may of course be restricted situations where it is safe. But I would bet it's fewer situations than you're guessing.)
You might also be interested in reading or signing up for updates to this language proposal.