gpt4 book ai didi

haskell - 显示 Haskell 程序的进度

转载 作者:行者123 更新时间:2023-12-02 19:41:17 25 4
gpt4 key购买 nike

我在 Haskell 中有一些对象的列表。我需要查明这些对象中是否有人满足某些条件。所以,我写了以下内容:

any (\x -> check x) xs

但问题是检查操作的开销非常大,而且列表也很大。我想查看运行时的当前进度,例如 50%(选中 1000/2000)。
我怎样才能做到这一点?

最佳答案

由于您想查看函数的进度(这是函数的副作用),最明显的解决方案是使用 monad。因此,首先要做的是制作 any 函数的单子(monad)版本:

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 函数的单子(monad)版本。除了检查给定列表中的任何项目是否满足给定谓词之外,它还允许我们产生副作用。

除了执行 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

希望这个回答对你有帮助。

关于haskell - 显示 Haskell 程序的进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19343695/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com