2017-01-10 1 views
4

주어진 디렉터리의 모든 json 파일을 결과으로 파싱하고 싶습니다.DataText.Lazy.IO를 사용하여 Aeson에서 JSON 파일을 구문 분석하는 방법

그래서 나는 컴파일

import qualified Data.Text.Lazy.IO as T 
import qualified Data.Text.Lazy.Encoding as T 

getFileContent :: FilePath -> IO B.ByteString 
getFileContent path = T.encodeUtf8 `fmap` T.readFile path 

내가 게으른 ByteString에 파일을로드 할 Data.Text.Lazy.IO로 시작

decodeResult :: Data.ByteString.Lazy.ByteString -> Maybe Result 

디코드 기능을 가지고,하지만 난에 달렸다 파일이 너무 많아서 withFile을 사용해야한다고 생각했습니다.

import System.IO 
import qualified Data.ByteString.Lazy as B 
import qualified Data.Text.Lazy.IO as T 
import qualified Data.Text.Lazy.Encoding as T 

getFileContent :: FilePath -> IO (Maybe Result) 
getFileContent path = withFile path ReadMode $ \hnd -> do 
    content <- T.hGetContents hnd 
    return $ (decodeAnalytic . T.encodeUtf8) content 

loadAllResults :: FilePath -> IO [Result] 
loadAllResults path = do 
    paths <- listDirectory path 
    results <- sequence $ fmap getFileContent (fmap (path ++) $ filter (endswith ".json") paths) 
    return $ catMaybes results 

이 버전에서는 게으른 io가 평가되지 않은 것 같습니다. 항상 빈 목록을 반환합니다. 하지만 만약 내가 getFileContent 함수 안에 내용을 인쇄한다면, 모든 것이 제대로 작동하는 것 같습니다.

getFileContent :: FilePath -> IO (Maybe Result) 
getFileContent path = withFile path ReadMode $ \hnd -> do 
    content <- T.hGetContents hnd 
    print content 
    return $ (decodeAnalytic . T.encodeUtf8) content 

내가 무엇을 놓치고 있는지 잘 모르겠다. 이런 종류의 것들에 대해 도관을 사용해야합니까?

+0

간단한 대답은 예, 도관 등을 사용하는 것입니다. 더 복잡한 대답은'loadAllResults'가 * 매우 믿을 수 없을 정도로 * 게으른 것입니다. 단순히'loadAllResults x'를 실행해도 실제로는 파일을 읽지 않습니다. 결과 목록을 평가하려고 할 때 동시에 모든 파일을 열고 읽으려고합니다. 게으름이'hGetContents'에서 나왔기 때문에'withFile'은 도움이되지 않습니다. - 게으른 텍스트가 아닌 IO로 전환을 시도하십시오. – user2407038

답변