4

ファイル/ウェブサーバーからのJSONデータを解析するためにaeson/attoparsecおよびconduit/conduit-http接続を使用しています。conduit-attoparsec私の問題は、パイプラインが常にこの例外をスローすることです...

ParseError {errorContexts = ["demandInput"], errorMessage = "not enough bytes", errorPosition = 1:1}

...ソケットが閉じられるか、EOF に達すると。パイプラインなどを介して結果のデータ構造を解析して渡すことは問題なく機能しますが、常にsinkParserこの例外をスローして終了します。私はこのようにそれを呼び出します...

j <- CA.sinkParser json

...ByteStrings をメッセージ構造に解析するコンジットの内部。

データがなくなったら (トップレベルの式がなくなったら)、パイプラインをきれいに終了させるにはどうすればよいですか? エラー文字列を見なくても、この例外を検出/区別する適切な方法はありますか?

ありがとう!

編集: 例:

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Control.Applicative
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import qualified Data.Conduit.Attoparsec as CA
import Data.Aeson
import Data.Conduit
import Data.Conduit.Binary
import Control.Monad.IO.Class

data MyMessage = MyMessage String deriving (Show)

parseMessage :: (MonadIO m, MonadResource m) => Conduit B.ByteString m B.ByteString
parseMessage = do
    j <- CA.sinkParser json
    let msg = fromJSON j :: Result MyMessage
    yield $ case msg of
        Success r -> B8.pack $ show r
        Error   s -> error s
    parseMessage

main :: IO ()
main =
    runResourceT $ do
        sourceFile "./input.json" $$ parseMessage =$ sinkFile "./out.txt"

instance FromJSON MyMessage where
    parseJSON j =
        case j of
        (Object o) -> MyMessage <$> o .: "text"
        _          -> fail $ "Expected Object - " ++ show j

サンプル入力 (input.json):

{"text":"abc"}
{"text":"123"}

出力:

out: ParseError {errorContexts = ["demandInput"], errorMessage = "not enough bytes", errorPosition = 3:1}

と out.txt:

MyMessage "abc"MyMessage "123"
4

1 に答える 1

4

これは次の場合に最適な使用例ですconduitParserEither

parseMessage :: (MonadIO m, MonadResource m) => Conduit B.ByteString m B.ByteString
parseMessage =
    CA.conduitParserEither json =$= awaitForever go
  where
    go (Left s) = error $ show s
    go (Right (_, msg)) = yield $ B8.pack $ show msg ++ "\n"

FP Haskell Center を使用している場合は、私のソリューションを IDE に複製できます。

于 2013-10-22T15:36:03.713 に答える