gpt4 book ai didi

haskell - 批量(串联)延迟消耗日志文件行

转载 作者:行者123 更新时间:2023-12-02 14:34:19 26 4
gpt4 key购买 nike

我有这个功能来懒惰地观看日志文件...

follow :: Handle -> IO [String]
follow h = unsafeInterleaveIO $ do
catch (do line <- hGetLine h
lines <- follow h
return $ line : lines)
(const (do threadDelay (1000 * 100)
follow h))

...这很棒,因为它返回一个无限列表,可以在附加日志文件时逐行处理,如下所示:

h <- openFile "test.log" ReadMode
ls <- follow h
mapM_ putStrLn ls

但现在我需要在处理之前将一些行连接在一起。 (一些日志条目是分成多行的 xml,我需要将它们放回一起)。我尝试了以下方法来做到这一点,但它永远不会终止,因为据我所知,follow 永远不会终止。

h <- openFile "test.log" ReadMode
ls <- follow h
mapM_ putStrLn (concatWhen (isPrefixOf "foo") ls)

concatWhen :: (String -> Bool) -> [String] -> [String]
concatWhen _ [] = []
concatWhen p as = let (xs, as') = span p as
(ys, rest) = break p as'
in (concat xs) : ys ++ (concatWhen p rest)

有什么好的方法吗?我是否需要在 follow 中进行行连接,或者是否有一种更优雅的方法可以对该函数返回的字符串数组进行操作?

如果有任何区别,可以通过检查内容来确定一行是否是需要连接的组的最后一行。

最佳答案

concatWhen p (x:xs)
| p x = let (ys,zs) = span p xs in concat (x:ys) : concatWhen zs
| otherwise = x : concatWhen p xs
concatWhen _ _ = []

应该足够懒。但如果第一行不满足 p :(所以你需要一个包装器

wrapConcatWhen p xxs@(x:_)
| p x = concatWhen p xxs
| otherwise = "" : concatWhen p xxs
wrapConcatWhen _ _ = []

但是,仔细观察一下,您的 concatWhen 也应该足够懒惰,也许效率会低一些,因为额外的 break 会分配一些对构造函数(如果不是)没有优化。

您遇到了什么问题?

关于haskell - 批量(串联)延迟消耗日志文件行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8928767/

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