In Haskell, un approccio possibile è utilizzare la memoria transazionale del software per questo. 
-- silly example mixing IO and STM
doOperation :: TVar Int -> IO ()
doOperation x = do -- IO monad
   putStrLn "Incrementing value!"
   atomically $ do -- STM monad
      v <- readTVar x
      -- putStrLn "We can't do I/O here, in the middle of STM!"
      -- print v
      writeTVar x $! v+1
   putStrLn "Incrementing complete."
 Usando   atomically   , possiamo eseguire azioni STM nel mezzo delle azioni IO. Questo ci consente di leggere e scrivere   x   , quindi di incrementarlo. In alternativa,   modifyTVar' (+1)    farebbe anche l'incremento più convenientemente, ma soprattutto volevo separare la lettura dalla scrittura. 
 Per confronto, non c'è modo di eseguire azioni IO nel mezzo della transazione atomica STM. Se proviamo a decommentare le azioni IO nel codice sopra, il compilatore genera un errore di tipo perché   IO    non è   STM   . Questo è importante, dal momento che non dobbiamo stampare   v    nel mezzo di una transazione che potrebbe ancora essere ripristinata - non possiamo annullare   print v   , o in generale altri calcoli di I / O che potrebbero anche usare il disco o il Rete. (Gli sviluppatori di GHC usano   launchMissiles    come esempio archetipo di IO con effetti collaterali internazionali, senza "annulla" possibile.) 
 Operativamente, l'implementazione del monad STM tiene traccia delle modifiche alla variabile   x   . Durante la lettura, registra il vecchio valore di   x    (nessun blocco in questo momento).
Durante la scrittura, anche il nuovo valore viene registrato, ma non scritto (nessun blocco).
Letture successive all'interno della transazione leggono il nuovo valore di   x    (nessun blocco). 
 Alla fine della transazione, entriamo nella fase di commit: blocchiamo tutte le variabili coinvolte (usando un dead lock free ordering). Quindi testiamo se contengono ancora i vecchi valori. In caso contrario, eseguiamo il rollback della transazione e riproviamo. Se lo fanno, scriviamo i nuovi valori (dal log), sblocchiamo le variabili e abbiamo finito. 
 STM non è efficiente quanto gli algoritmi personalizzati per l'esclusione reciproca / l'esclusione dal deadlock che possono essere utilizzati per problemi specifici. È tuttavia molto generale e, a differenza delle serrature di base, molto componibile e flessibile.
Pure FP rende l'approccio più sicuro controllando che il programmatore utilizzi solo operazioni sicure nelle transazioni (senza IO).