Tôi đang cố gắng viết một chương trình Haskell để phân tích cú pháp tệp văn bản lớn (khoảng 14Gb), nhưng tôi không thể hiểu làm thế nào để làm cho nó miễn phí dữ liệu không sử dụng từ bộ nhớ hay không để làm cho ngăn xếp tràn trong foldr. Đây là nguồn chương trình:Tại sao chương trình Haskell của tôi kết thúc bằng lỗi bộ nhớ?
import qualified Data.ByteString.Lazy.Char8 as LBS
import qualified Data.ByteString.Lex.Lazy.Double as BD
import System.Environment
data Vertex =
Vertex{
vertexX :: Double,
vertexY :: Double,
vertexZ :: Double}
deriving (Eq, Show, Read)
data Extent =
Extent{
extentMax :: Vertex,
extentMin :: Vertex}
deriving (Eq, Show, Read)
addToExtent :: Extent -> Vertex -> Extent
addToExtent ext vert = Extent vertMax vertMin where
(vertMin, vertMax) = (makeCmpVert max (extentMax ext) vert, makeCmpVert min (extentMin ext) vert) where
makeCmpVert f v1 v2 = Vertex(f (vertexX v1) (vertexX v2))
(f (vertexY v1) (vertexY v2))
(f (vertexZ v1) (vertexZ v2))
readCoord :: LBS.ByteString -> Double
readCoord l = case BD.readDouble l of
Nothing -> 0
Just (value, _) -> value
readCoords :: LBS.ByteString -> [Double]
readCoords l | LBS.length l == 0 = []
| otherwise = let coordWords = LBS.split ' ' l
in map readCoord coordWords
parseLine :: LBS.ByteString -> Vertex
parseLine line = Vertex (head coords) (coords!!1) (coords!!2) where
coords = readCoords line
processLines :: [LBS.ByteString] -> Extent -> Extent
processLines strs ext = foldr (\x y -> addToExtent y (parseLine x)) ext strs
processFile :: String -> IO()
processFile name = do
putStrLn name
content <- LBS.readFile name
let (countLine:recordsLines) = LBS.lines content
case LBS.readInt countLine of
Nothing -> putStrLn "Can't read records count"
Just (recordsCount, _) -> do
print recordsCount
let vert = parseLine (head recordsLines)
let ext = Extent vert vert
print $ processLines recordsLines ext
main :: IO()
main = do
args <- getArgs
case args of
[] -> do
putStrLn "Missing file path"
xs -> do
processFile (head xs)
return()
Tệp văn bản chứa các dòng có ba số dấu phẩy động được phân tách bằng ký tự khoảng trắng. Chương trình này luôn cố gắng chiếm toàn bộ bộ nhớ miễn phí trên máy tính và bị lỗi do lỗi bộ nhớ.
Lưu ý: Tôi nghĩ rằng bạn có lỗi trong 'addToExtent', xem ghi chú đã thêm trong câu trả lời của tôi. –
Cảm ơn, vâng, đó là một sai lầm. Tôi sẽ sửa nó. – KolKir
bạn đang sử dụng phiên bản GHC nào và bạn đang biên soạn như thế nào? – jberryman