История изменений
Исправление quasimoto, (текущая версия) :
Хотя такой вариант ест уже кучу.
А вот вариант с foldM/replicate нормально фьюзится. Можно вместо sum' написать sumM :: (Monad m, Num a) => [m a] -> m a:
sumM :: (Monad m, Num a) => [m a] -> m a
sumM = foldM (\a e -> (return $!) . (+ a) =<< e) 0
main :: IO ()
main = print =<< sumM (replicate 10000000 randomNorm)
Видимо, [m a] -> m a и [a] -> a это разные вещи, первое как liftM sum' . sequence от второго не работает в константной памяти. Как и liftM sum' . replicateM (replicateM n x = sequence (replicate n x)).
Исправление quasimoto, :
Хотя такой вариант ест уже кучу.
А вот вариант с foldM/replicate нормально фьюзится. Можно вместо sum' написать sumM :: (Monad m, Num a) => [m a] -> m a:
sumM :: (Monad m, Num a) => [m a] -> m a
sumM = foldM (\a e -> (return $!) . (+ a) =<< e) 0
main :: IO ()
main = print =<< sumM (replicate 10000000 randomNorm)
Видимо, [m a] -> m a и [a] -> a это разные вещи, второе как liftM sum' . sequence не работает в константной памяти. Как и liftM sum' . replicateM (replicateM n x = sequence (replicate n x)).
Исходная версия quasimoto, :
Хотя такой вариант ест уже кучу.
А вот вариант с foldM/replicate нормально фьюзится. Можно вместо sum' написать sumM :: (Monad m, Num a) => [m a] -> m a:
sumM :: (Monad m, Num a) => [m a] -> m a
sumM = foldM (\a e -> (return $!) . (+ a) =<< e) 0
main :: IO ()
main = print =<< sumM (replicate 10000000 randomNorm)
Так что вопрос — можно ли [m a] -> m a выразить через [a] -> a и сохранить эти свойства про константную память? Через liftM sum' . sequence не получается.