考慮下面的例子:在大名單正在使用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
)。但是,我無法在Haskell標準庫中找到與safeMapM
類似的功能。
使用mapM
(或sequence
)仍然被認爲是良好做法嗎?
如果是這樣,儘管存在堆棧空間溢出的危險,爲什麼它被認爲是良好的做法?
如果不是您建議使用哪種替代方案?
也許'mapM'更快,如果它不溢出,因爲你不必'倒退'?你測量過了嗎? – 2013-03-21 14:08:14
你可以發佈你用來測試的'Main'模塊嗎? – jberryman 2013-03-21 14:12:46
此外,還有一些單子(如'Control.Monad.State.Lazy'),其中'take 100 <$> mapM id [1 ..]'終止。 'take 100 <$> safeMapM id [1 ..]'不可能終止,不管單子是什麼 – 2013-03-21 15:06:05