Per capire come utilizzare i trasformatori monad, ho scritto il seguente codice senza uno. Legge l'input standard riga per riga e visualizza ogni riga invertita fino a quando viene rilevata una riga vuota. Conta anche le linee usando State
e alla fine visualizza il numero totale.Utilizzare due monadi senza trasformatore
import Control.Monad.State
main = print =<< fmap (`evalState` 0) go where
go :: IO (State Int Int)
go = do
l <- getLine
if null l
then return get
else do
putStrLn (reverse l)
-- another possibility: fmap (modify (+1) >>) go
rest <- go
return $ do
modify (+1)
rest
Desidero aggiungere il numero di riga corrente prima di ogni riga. Sono stato in grado di farlo con StateT
:
import Control.Monad.State
main = print =<< evalStateT go 0 where
go :: StateT Int IO Int
go = do
l <- lift getLine
if null l
then get
else do
n <- get
lift (putStrLn (show n ++ ' ' : reverse l))
modify (+1)
go
La mia domanda è: come fare lo stesso nella versione senza trasformatore monade?
Mi rendo conto che. Non sto cercando una versione senza un trasformatore monad per motivi di efficienza, voglio solo vedere come sarebbe e imparare qualcosa confrontando i due, sperando di ottenere un migliore apprezzamento della necessità di trasformatori monad. – ByteEater
Inoltre, eseguire il calcolo dello stato accumulato su ogni linea è qualcosa che ho considerato e respinto proprio per questo motivo: non sembra il modo giusto di usare le monade, un semplice 'Int 'sarebbe una scelta migliore. Inoltre, con l'incremento non fa la differenza, ma sarebbe sbagliato concettualmente, dal momento che il calcolo dello 'stato' è costruito anteponendo le azioni' modify (+1) ', quindi se avessi ad es. 'modify (+ length l)', non funzionerebbe come dovrebbe. – ByteEater
@ByteEater, il modo per farlo senza un trasformatore di monade è semplicemente passare il 'Int 'a mano (fastidioso) o usare un' IORef' (limitato a cose di tipo IO-IO e potenzialmente inefficiente, ma va bene se il la scatola è inevitabile o gli aggiornamenti sono rari). Non so cos'altro stai cercando. – dfeuer