Se ho un tipo come data T = T Int String
e una funzione in questo modo:GHC crea una nuova copia di un oggetto quando lo decostruisce e lo ricostruisce?
identity :: T -> T
identity (T a b) = T a b
Dopo la decostruzione nel pattern matching, fa GHC creare un nuovo oggetto T che contiene riferimenti alla stessa Int e String? O restituisce esattamente lo stesso oggetto (con lo stesso indirizzo di memoria) che ha ricevuto? Capisco che sono semanticamente equivalenti, sono solo curioso.
Vedo. Questo è un po 'deludente. In realtà stavo pensando al caso in cui si ha una struttura di dati persistente nidificata (come un albero binario) e si voleva inserire un valore che era già presente. Avresti bisogno di una funzione di supporto come "insert :: (Ord a) => a -> Tree a -> Maybe (Tree a)" che restituiva un Nothing se l'elemento era già presente per evitare di ricostruire il percorso del valore . –
@Ramith Che distrugge la pigrizia purtroppo; tutte le chiamate sul percorso fino al nodo foglia devono attendere la restituzione della chiamata definitiva prima di sapere se restituiscono un riferimento a un nodo costruttore esistente o ne allocano uno nuovo, il che significa forzare la radice il passo costringe tutto. Quindi, se mai vuoi scegliere tra queste proprietà (la pigrizia o la ricostruzione di alberi identici), allora deve essere programmato esplicitamente (come tramite l'helper Maybe (Tree a)) piuttosto che il comportamento implicito del compilatore. – Ben
In questo caso, 'unsafeCoerce' è sicuro? Voglio dire "O una b" e "O una c" hanno lo stesso argomento di "Sinistra", quindi sembra plausibile che il costruttore di 'Sinistra' possa essere forzato senza problemi (e probabilmente lo è), tuttavia esiste una * garanzia * su questo? – Bakuriu