Haskell: ascensore vs liftIO
-
29-09-2019 - |
Domanda
In quali situazioni deve liftIO
essere utilizzato? Quando sto usando ErrorT String IO
, le opere di funzione lift
per sollevare le azioni IO in ErrorT
, così liftIO
sembra superfluo.
Soluzione
lift
solleva sempre dallo strato "precedente". Se avete bisogno di ascensore dal secondo strato, si avrebbe bisogno lift . lift
e così via.
D'altra parte, liftIO
solleva sempre dallo strato IO (che, quando presente, è sempre in fondo alla pila). Quindi, se avete più di 2 strati di monadi, si potranno apprezzare liftIO
.
Confronto il tipo dell'argomento nei seguenti lambda:
type T = ReaderT Int (WriterT String IO) Bool
> :t \x -> (lift x :: T)
\x -> (lift x :: T) :: WriterT String IO Bool -> T
> :t \x -> (liftIO x :: T)
\x -> (liftIO x :: T) :: IO Bool -> T
Altri suggerimenti
liftIO è solo una scorciatoia per l'IO Monade, a seconda di quale la Monade si è in. In sostanza, liftIO equivale all'utilizzo di un numero variabile di ascensori. In un primo momento questo può sembrare ridondante, ma utilizzando liftIO ha un grande vantaggio: rende il codice IO indpendent della costruzione vera e propria Monade in modo da poter riutilizzare lo stesso codice, non importa il numero di strati vostro finale Monade è stato costruito di (questo è molto importante quando si scrive un trasformatore monade).
Sulla mano Ohter, liftIO non è venuta per libero, come ascensore fa: i trasformatori Monade che si sta utilizzando deve avere il supporto per esso, ad esempio, la Monade si è in deve essere un'istanza della classe MonadIO, ma la maggior parte Monadi al giorno d'oggi fare (e, naturalmente, il tipo-ispettore controllerà questo per voi al momento della compilazione: questa è la forza di Haskell).