Vorrei abortire opzionalmente un'azione getChar
. devo la seguente funzione:Come interrompere getChar in sicurezza?
getChar' :: (Char -> IO()) -> IO (IO())
In caso di abort <- getChar' callback
, un carattere viene letto dallo standard input, salvo abort
è chiamato prima di un carattere è disponibile. Se un carattere viene letto, viene chiamato callback
.
Ho il seguente prototipo di attuazione:
import Control.Monad
import Control.Concurrent
getChar' :: (Char -> IO()) -> IO (IO())
getChar' callback = do
v <- newEmptyMVar
tid <- forkIO $ do
c <- getChar
b <- tryPutMVar v()
when b $ callback c
return $ do
b <- tryPutMVar v()
when b $ killThread tid
Il problema è che killThread
può interrompere il filo dopo aver letto il carattere, ma prima di mettere ()
in MVAR.
Non ho idea di come risolvere questo problema, è possibile del tutto con il pacchetto base? In caso contrario, hai visto una funzione simile implementata in altri pacchetti?
Grazie! STM e un buffer globale sono inevitabili qui? Cosa ne pensi, potrebbe 'getChar' essere definito in' IO' anche senza compromettere la sua semantica? Edit: Suppongo di sì perché 'IO' potrebbe avere uno stato globale. –
Mi chiedo perché 'getChar ':: (Char -> IO()) -> IO (IO())' non sia in 'Prelude' o' System.IO', ha semantica semplice e sembra impossibile definire con costrutti esistenti (voglio dire senza il parametro 'Buffer'). –
1. Sì, ci sono hack per creare variabili globali in Haskell. –