考虑下面的例子:在大名单正在使用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