Рассмотрим следующий пример:Использует mapM/последовательность считается хорошей практикой?
safeMapM f xs = safeMapM' xs []
where safeMapM' [] acc = return $ reverse acc
safeMapM' (x:xs) acc = do y <- f x
safeMapM' xs (y:acc)
mapM return largelist -- Causes stack space overflow on large lists
safeMapM return largelist -- Seems to work fine
Использование mapM
на больших списках вызывает переполнение стека пространства в то время как safeMapM
, кажется, работает нормально (с использованием GHC 7.6.1 с -O2
). Однако я не смог найти функцию, аналогичную safeMapM
в стандартных библиотеках Haskell.
По-прежнему считается хорошей практикой использования mapM
(или sequence
в этом отношении)?
Если да, то почему это считается хорошей практикой, несмотря на опасность переполнения пространства стека?
Если нет, какой вариант вы предлагаете использовать?
Возможно, 'mapM' быстрее, если он не переполняется, потому что вам не нужно« обращать »? Вы его измеряли? –
Можете ли вы разместить модуль 'Main', который вы использовали для тестирования? – jberryman
Кроме того, существуют монады (например, 'Control.Monad.State.Lazy'), где-то вроде' take 100 <$> mapM id [1 ..] 'завершается. 'take 100 <$> safeMapM id [1 ..]' не может завершиться, независимо от монады –