haskell - clonar - copiar objeto typescript
¿Hace GHC una nueva copia de un objeto cuando se deconstruye y reconstruye? (2)
Si tengo un tipo de data T = T Int String
tipo data T = T Int String
y una función como esta:
identity :: T -> T
identity (T a b) = T a b
Después de la deconstrucción en la coincidencia de patrones, ¿GHC crea un nuevo objeto T que contiene referencias al mismo Int y String? ¿O devuelve exactamente el mismo objeto (con la misma dirección de memoria) que recibió? Entiendo que son semánticamente equivalentes, solo tengo curiosidad.
En general, GHC asignará un nuevo valor en lugar de reutilizar el argumento en esa situación. En este caso particular podrías escribir algo como
f :: T -> T
f t@(T x y) = t
Para reutilizar explícitamente el argumento. Desafortunadamente, en uno de los casos donde realmente querrías esto -
fmap :: (a -> b) -> Either e a -> Either e b
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x
- GHC asignará un nuevo valor de Left
, y no puede simplemente reutilizar el argumento, porque el resultado tiene un tipo diferente. Que yo sepa, no hay manera de decirle a GHC que reutilice el argumento en este caso que no sea unsafeCoerce
.
Puedes probar esto fácilmente con -ddump-simpl
. Una asignación de un valor de un ADT se mostrará como una aplicación de un constructor de datos.
En este caso, GHC detecta que puede reutilizar el valor, e incluso que no tiene que realizar la coincidencia de patrones:
module I where
data T = T Int String
identity :: T -> T
identity (T a b) = T a b
-
rwbarton@morphism:/tmp$ ghc -ddump-simpl I
[1 of 1] Compiling I ( I.hs, I.o )
==================== Tidy Core ====================
Result size of Tidy Core = {terms: 3, types: 3, coercions: 0}
I.identity :: I.T -> I.T
[GblId, Arity=1, Caf=NoCafRefs, Str=DmdType]
I.identity = / (ds_dHN :: I.T) -> ds_dHN
Esto sucede incluso sin las optimizaciones habilitadas, y también funciona en ADT con más de un constructor.