LINUX.ORG.RU

История изменений

Исправление 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 не получается.