data Thing = Thing {a :: Int, b :: Int, c :: Int, (...) , z :: Int} deriving Show
foo = Thing 1 2 3 4 5 (...) 26
mkBar x = x { c = 30 }
main = do print $ mkBar foo
What is copied over when I mutate foo in this way? As opposed to mutating part of a structure directly.
Data Thing = Thing {a :: IORef Int, b :: IORef Int, (...) , z :: IORef Int}
instance Show Thing where
(...something something unsafePerformIO...)
mkFoo = do a <- newIORef 1
(...)
z <- newIORef 26
return Thing a b (...) z
mkBar x = writeIORef (c x) 30
main = do foo <- mkFoo
mkBar foo
print foo
Does compiling with optimizations change this behavior?
In the first example, the pointers to the unchanged
Intcomponents are copied (and the constructor tag, if you wish to say so). It doesn’t make much difference whether anIntor a pointer to one is copied, but if the components were large structures, it would.Since the fields are not strict, the behaviour is, afaik, independent of optimisation. If the fields were strict, with optimisations, they might be unpacked into the constructor and then the raw
Int#values would be copied.In the second example, nothing is copied, the contents of the
IORefare overwritten.