Как я могу сложить ленивый список, используя монадическое действие в постоянном пространстве? Проблема, которую я пытаюсь решить, заключается в агрегировании большого файла, и я считаю, что ради производительности мне нужна изменчивость. У меня есть реализация, работающая в ST с использованием изменяемых векторов, но она использует слишком много памяти. Ниже приведен пример того, что я пытаюсь сделать. Я также коротко экспериментировал с Conduit, но, похоже, это не улучшило.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
кабелепровода:
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
Для настройки производительности: похоже, что 'STT s Identity' будет иметь некоторые накладные расходы над обычными' ST s'; если вам не нужны уникальные полномочия STT, вы можете просто использовать 'ST'. – dfeuer
@dfeuer Действительно, я могу удалить его, но я положил его на реализацию, изначально ожидающую, что вам нужно будет внедрить 'Either', и она перешла. Спасибо за совет! – ryachza