If I have a type like data T = T Int String
and a function like so:
identity :: T -> T
identity (T a b) = T a b
After the deconstruction in the pattern matching, does GHC create a new T object containing references to the same Int and String? Or does it return the exact same object (with the same memory address) it received? I understand they're semantically equivalent, I'm just curious.
Objects are assigned and copied by reference. In other words, a variable stores not the “object value”, but a “reference” (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object itself.
When an object variable is copied, the reference is copied, but the object itself is not duplicated. Now we have two variables, each storing a reference to the same object: As you can see, there’s still one object, but now with two variables that reference it.
But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level. Also we can use the method Object.assign for that. Object.assign( dest, [ src1, src2, src3 ...]) The first argument dest is a target object.
When an object variable is copied, the reference is copied, but the object itself is not duplicated. Now we have two variables, each storing a reference to the same object: As you can see, there’s still one object, but now with two variables that reference it. We can use either variable to access the object and modify its contents:
In general GHC will allocate a new value rather than reuse the argument in that situation. In this particular case you could write something like
f :: T -> T
f t@(T x y) = t
to explicitly reuse the argument. Unfortunately, in one of the cases where you'd really want this --
fmap :: (a -> b) -> Either e a -> Either e b
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
-- GHC will allocate a new Left
value, and you can't simply reuse the argument, because the result has a different type. As far as I know there's no way to tell GHC to reuse the argument in this case other than unsafeCoerce
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With