Come posso piegare una lista pigra usando un'azione monadica nello spazio costante? Il problema che sto cercando di risolvere è l'aggregazione di un file di grandi dimensioni, e credo che per motivi di prestazioni richieda mutabilità. Ho un'implementazione che funziona in ST usando vettori mutabili, ma usa troppa memoria. Di seguito è riportato un esempio di ciò che sto tentando. Ho anche sperimentato brevemente con Conduit, ma questo non sembrava fornire alcun miglioramento.Monadic Fold in Constant Space
ST forM_:
import Control.Monad (forM_)
import Control.Monad.ST.Trans as STT
import Control.Monad.Identity as Identity
testST :: Int
testST = do
Identity.runIdentity $ STT.runST $ do
a <- STT.newSTRef 0
forM_ [1..10000000] (\x -> do
a' <- STT.readSTRef a
STT.writeSTRef a (a' + x)
)
STT.readSTRef a
condotto:
import Data.Conduit (($=),(=$),($$))
import qualified Data.Conduit as C
import qualified Data.Conduit.List as CL
testCL :: IO Int
testCL = CL.sourceList [1..10000000] $$ CL.foldM (\a x -> return (a + x)) 0
Per l'ottimizzazione delle prestazioni: sembra che "STT s Identity' abbia un certo overhead di allocazione rispetto al solito' ST s'; se non hai bisogno dei peculiari poteri 'STT', potresti voler usare' ST'. – dfeuer
@dfeuer Anzi, posso rimuoverlo, ma l'ho messo nell'implementazione inizialmente aspettandomi di dover inserire 'Either' e l'ho trasferito. Grazie per il consiglio! – ryachza