gpt4 book ai didi

parsing - 将普通的 attoparsec 解析器代码转换为基于管道/管道的代码

转载 作者:行者123 更新时间:2023-12-04 17:20:04 27 4
gpt4 key购买 nike

我使用 attoparsec 编写了以下解析代码:

data Test = Test {
a :: Int,
b :: Int
} deriving (Show)

testParser :: Parser Test
testParser = do
a <- decimal
tab
b <- decimal
return $ Test a b

tParser :: Parser [Test]
tParser = many' $ testParser <* endOfLine

这适用于小文件,我是这样执行的:
main :: IO ()
main = do
text <- TL.readFile "./testFile"
let (Right a) = parseOnly (manyTill anyChar endOfLine *> tParser) text
print a

但是当文件大小大于 70MB 时,它会消耗大量内存。作为解决方案,我想我会使用 attoparsec-conduit .经过他们的 API ,我不知道如何让它们一起工作。我的解析器的类型是 Parser Test但它是 sinkParser实际上接受 Parser a b 类型的解析器.我对如何在常量内存中执行这个解析器感兴趣? (基于管道的解决方案也是可以接受的,但我不习惯管道 API。)

最佳答案

Parser的第一个类型参数只是输入的数据类型( TextByteString )。您可以提供您的 testParser函数作为 sinkParser 的参数它会正常工作。这是一个简短的例子:

{-# LANGUAGE OverloadedStrings #-}
import Conduit (liftIO, mapM_C, runResourceT,
sourceFile, ($$), (=$))
import Data.Attoparsec.Text (Parser, decimal, endOfLine, space)
import Data.Conduit.Attoparsec (conduitParser)

data Test = Test {
a :: Int,
b :: Int
} deriving (Show)

testParser :: Parser Test
testParser = do
a <- decimal
space
b <- decimal
endOfLine
return $ Test a b

main :: IO ()
main = runResourceT
$ sourceFile "foo.txt"
$$ conduitParser testParser
=$ mapM_C (liftIO . print)

关于parsing - 将普通的 attoparsec 解析器代码转换为基于管道/管道的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24058882/

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