Questo C variabile può concettualmente essere descritto come la creazione di un nuovo array identico a un array di input ma con 1 come primo elemento:Haskell: utilizzare ultimo riferimento a una variabile per creare efficacemente un nuovo codice
int* retire_and_update(int* arr) {
arr[0] = 1;
return arr;
}
Questo è una funzione pura (wink wink nudge nudge) purché non vengano fatti ulteriori riferimenti all'array di input e ai suoi elementi. Il sistema di tipo C non imporrà questo per noi, ma sembra in linea di principio applicabile.
Il codice che genera gcc è semplice ed efficace:
retire_and_update:
movq %rdi, %rax
movl $1, (%rdi)
ret
nostra funzione realizza l'apparentemente impossibile creando una nuova matrice in tempo costante e senza usare memoria aggiuntiva. Bello. È possibile scrivere una funzione Haskell con input e output di tipo array che possa essere validamente implementata con un codice simile? C'è un modo per esprimere "questo è l'ultimo riferimento a questa variabile" in modo che una pura funzione possa cannibalizzare la variabile dietro le quinte?
Se la funzione viene evidenziata, non è necessario che avvenga qualcosa di interessante, quindi supponiamo che il chiamante e la funzione vengano compilati separatamente.
IIUC "tipi unicità", o similmente tipi lineari, fanno questo. Sfortunatamente queste non sono una caratteristica del sistema di tipo Haskell. Il modo convenzionale in Haskell è di usare [il monad di 'ST'] (https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Monad-ST.html) per ottenere la mutazione in un concettualmente impostazione pura (che entra temporaneamente in una monade con stato mutabile, ma il sistema tipo garantisce che il calcolo è deterministico e lo stato non perde). È una cosa molto diversa da quella di cui stai parlando. – luqui
[Pulisci] (http://clean.cs.ru.nl/Clean) è un linguaggio funzionale che utilizza i tipi di unicità, anch'esso influenzato da Haskell. – chi