Domanda

Ho scritto una funzione in Haskell che richiede alcuni parametri come Word32, stringa (ignorare la curry) e le uscite IO Word32.Ora, questa è una funzione nel senso reale: Per gli stessi ingressi, l'uscita sarà sempre la stessa .Non ci sono effetti collaterali.Il motivo per cui la funzione restituisce IO Word32 invece di Word32 è che la funzione aggiorna molti registri di cambio di feedback lineari a 32 bit (LFSR) e altri registri più volte in un loop per calcolare l'uscita Word32 finale.

La mia domanda è questa: dato che questa funzione non ha effettivamente effetti collaterali , è possibile nascondere quegli aggiornamenti del registro all'interno dell'attuazione della funzione in modo che la funzione restituisca Word32 e non Io Word32?Se è così, come?

È stato utile?

Soluzione

Sì! Haskell può farlo.

The St Monad

Se usi effettivamente lo stato mutabile (registri), che sono completamente nascosti dall'osservatore al di fuori della funzione, allora sei in St monad , una monaca solo per gli effetti di memoria. Entra nel St World tramite runST, e quando si esce dalla funzione, tutti gli effetti sono garantiti per non essere visibili.

È precisamente il giusto ambiente computazionale per lavorare con stato locale e mutabile.

Stato puramente funzionale: lo stato monad

Se, tuttavia, non stai effettivamente registri o cellule mutanti, ma piuttosto aggiornare un valore puramente funzionale molte volte, è disponibile un ambiente più semplice: lo stato monad . Questo non consente stato mutabile, ma dà un'illusione dello stato locale.

Io e Unfaperformmio

Infine, se hai effetti locali e mutabili, come nella monada ST, ma per qualche motivo o per un altro, avrai bisogno di operazioni IO su tale stato (come tramite una chiamata FFI), è possibile simulare il ST MONAD, con quasi altrettanto sicurezza, utilizzando unsafePerformIO, invece di runST, per introdurre un ambiente IO locale. Poiché Io Monad non ha dei bei tipi per far rispettare l'astrazione, dovrai assicurarti manualmente che gli effetti collaterali non saranno osservabili.

Altri suggerimenti

Se hai importato tale funzione utilizzando il FFI, basta rimuovere il IO dal tipo di ritorno.Altrimenti, utilizzare unsafePerformIO :: IO a -> a da System.IO.Unsafe.Si prega di notare che questa funzione è una delle funzioni più pericolose di Haskell.Non usarlo, se non stai davvero scherzando sulle conseguenze.Ma per il tuo scopo, sembra ok.

Sì, questo sarebbe un uso legittimo di Unfaperformformmio. Ma è solo ok se sei davvero sicuro che non ci siano effetti visibili.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top