首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >显示Haskell程序的进度

显示Haskell程序的进度
EN

Stack Overflow用户
提问于 2013-10-13 17:29:49
回答 4查看 1.5K关注 0票数 18

我在Haskell中有一些对象的列表。我需要找出这些对象中是否有人满足特定条件。因此,我写了以下内容:

any (\x -> check x) xs

但问题是,检查操作非常昂贵,并且列表相当大。我希望看到运行时的当前进度,例如50% (1000/2000 checked).

我怎么能做到这一点?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-10-13 19:33:45

由于您希望查看函数的进度(这是函数的副作用),因此最明显的解决方案是使用monad。因此,首先要做的是创建any函数的一元版本:

anyM :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
anyM _ []        = return False
anyM pred (x:xs) = reduce (pred x) xs
    where reduce acc []     = acc
          reduce acc (x:xs) = do
              condition <- acc
              if condition
                  then return condition
                  else reduce (pred x) xs

上面的函数anyMany函数的一元版本。除了检查给定列表中的任何项是否满足给定的谓词之外,它还允许我们产生副作用。

除了执行any函数之外,我们还可以使用anyM函数创建另一个函数,该函数显示一个进度条作为副作用,如下所示:

anyVar :: (a -> Bool) -> [a] -> IO Bool
anyVar pred xs = anyM check $ zip [1..] xs
    where check (n,x) = do
            putStrLn $ show n ++ " checked. "
            return $ pred x

请注意,因为我们事先不知道列表的长度,所以我们只显示列表中选中的项数。如果我们事先知道列表中的项目数,那么我们可以显示一个更具信息性的进度条:

anyFix :: (a -> Bool) -> Int -> [a] -> IO Bool
anyFix pred length xs = anyM check $ zip [1..] xs
    where check (n,x) = do
            putStrLn $ show (100 * n `div` length) ++ "% (" ++
                show n ++ "/" ++ show length ++ " checked). "
            return $ pred x

对于无限列表和事先不知道长度的列表,可以使用anyVar函数。对预先知道长度的有限列表使用anyFix函数。

如果列表很大,并且事先不知道列表的长度,那么length函数将需要遍历整个列表以确定其长度。因此,使用anyVar会更好。

最后,总结一下如何使用上面的函数:

main = anyFix (==2000) 2000 [1..2000]

在您的情况下,您可以改为执行以下操作:

main = anyVar check xs

希望这个答案对你有所帮助。

票数 17
EN

Stack Overflow用户

发布于 2013-10-13 17:42:49

最天真和直接的方法是实现你自己的

anyM :: (a -> Bool) -> [a] -> IO Bool

打印进度条(例如,使用terminal-progress-bar)。

但请注意,为了计算百分比,您必须评估完整的列表。这打破了懒惰,并可能对程序的空间行为产生不良和有害的影响。

也有使用unsafePerformIOunsafeInterleaveIO的方法,允许您监视纯计算(如any),请参阅bytestring-progress的示例。但这是一个可疑的设计,只有当您知道您了解其后果时,才应该使用它。

票数 7
EN

Stack Overflow用户

发布于 2013-10-13 20:52:52

我只需使用Debug.Trace.trace并跟踪当前位置,如下所示:

any (\(i,x) -> trace (showProgress i (length xs)) $ check x) $ zip [1..] xs
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19343695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档