gpt4 book ai didi

haskell - 管道管道跳过流的某些元素

转载 作者:行者123 更新时间:2023-12-02 00:53:07 24 4
gpt4 key购买 nike

我尝试使用 Haskell 的 Conduit 库实现一个简单的字数统计:

wordcountCv2 :: IO ()
wordcountCv2 = do
hashMap <- runConduitRes $ sourceFile "input.txt"
.| decodeUtf8C
.| omapCE Data.Char.toLower
.| peekForeverE (do
word <- takeWhileCE isAlphaNum
dropCE 1
return word)
.| foldMC insertInHashMap empty
print (toList hashMap)

insertInHashMap x v = do
return (insertWith (+) v 1 x)

问题是这个函数对小/中输入文件工作正常,但随着文件大小的增长,它往往会破坏一些单词。例如,如果我使用一个包含 100 个单词“hello”的小文件,结果是:[("hello",100)],如果 hellos 是例如 100000,则结果是:[("hello", 99988),("he",6),("hell",6),("o",6),("llo",6)]。文件越大,断字就越多。我的实现有什么问题吗?

最佳答案

气正确commented那个 takeWhileCE 返回 ()并将结果发送到下游而不是返回它。然而,他们在一件事情上是错误的:事实上,这就是问题所在。

您的管道在块流上运行,这也是 takeWhileCE 的原因之一将结果发送到下游,以便它可以将输入拆分保留在原始块边界上。这样,它不会仅仅因为您可能会收到一长串匹配值而强制您消耗无限内存。

但是,如果您想组合构成每个单词的潜在多个块,则需要做更多的工作。通过 foldC 发送它们是这样做的一种方法。

        .| peekForeverE (do
word <- takeWhileCE isAlphaNum .| foldC
dropCE 1
yield word)

在您的情况下,使用 splitOnUnboundedE 更容易组合器可以为您完成这一切。

        .| splitOnUnboundedE (not . isAlphaNum)

关于haskell - 管道管道跳过流的某些元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56134904/

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