2012-03-15 15 views
14

Ho bisogno di usare un elenco di trasformatore monad. Ho letto che ci sono potenziali problemi con ListT IO da Control.Monad.List, dal momento che IO non è commutativo, quindi sto guardando ListT done right. Ma sto ricevendo un comportamento inaspettato.lista monad transformer

considerare questo semplice test:

test = runListT $ do 
    x <- liftList [1..3] 
    liftIO $ print x 
    y <- liftList [6..8] 
    liftIO $ print (x,y) 

Utilizzando Control.Monad.List:

Main> test 
1 
(1,6) 
(1,7) 
(1,8) 
2 
(2,6) 
(2,7) 
(2,8) 
3 
(3,6) 
(3,7) 
(3,8) 
[(),(),(),(),(),(),(),(),()] 

Utilizzando "ListT fatto bene":

Main> test 
1 
(1,6) 

È questo un problema con " ListT fatto bene "o sto solo usando sbagliato? C'è un'alternativa preferita?

Grazie!

risposta

8

questo potrebbe essere intenzionale da parte del suo autore, poiché essi dicono

Consente ogni elemento della lista ha i suoi effetti collaterali, che si ottiene solo `excecuted' se questo elemento della lista è veramente controllato

Non sono sicuro, però. In ogni caso, è possibile utilizzare questa funzione per sequenziare l'intero lista:

runAll_ :: (Monad m) => ListT m a -> m() 
runAll_ (ListT m) = runAll_' m where 
    runAll_' m = do 
     mm <- m 
     case mm of 
      MNil   -> return() 
      _ `MCons` mxs -> runAll_' mxs 

E un analogo runAll che restituisce un elenco dovrebbe essere facile da costruire.

main = runAll_ $ do 
    x <- liftList [1..3] 
    liftIO $ print x 
    y <- liftList [6..8] 
    liftIO $ print (x,y) 

1 
(1,6) 
(1,7) 
(1,8) 
2 
(2,6) 
(2,7) 
(2,8) 
3 
(3,6) 
(3,7) 
(3,8) 
+0

Hmm, ok questo ha senso, e l'idea di 'runAll_' è abbastanza bella! Mi aspettavo un comportamento simile al nidificato per cicli con istruzioni di stampa in un linguaggio imperativo. Ma se "ListT fatto bene" è pigro, perché sta ancora eseguendo effetti collaterali per i capi delle liste? –

+0

Si presume che tu voglia sempre almeno il primo elemento, quindi avvolge "l'intera lista" in "m", e avvolge anche il cdr in "m"; l'auto non è avvolta. Se fai la sequenza della "lista intera", espone solo la macchina. – Owen