pipes-binary
と を使用してこれを行うことができますpipes-bytestring
。これがあなたの利益のためのヘルパー関数です:
import Control.Monad (void)
import Data.Binary
import Pipes
import Pipes.Binary (decodeMany)
import Pipes.ByteString (fromHandle)
import qualified Pipes.Prelude as P
import System.IO
decodeHandle :: (Binary a) => Handle -> Producer a IO ()
decodeHandle handle = void $ decodeMany (fromHandle handle) >-> P.map snd
void
とmap snd
が存在するのは、decodeMany
実際にはより多くの情報 (バイト オフセットや解析エラーなど) を返すためです。本当にその情報が必要な場合は、それらを削除してください。
を使用する方法の例を次に示しますdecodeHandle
。簡単なスケルトンを使用して、Trade
一緒に投げました。
data Trade = Trade
instance Binary Trade where
get = return Trade
put _ = return ()
instance Show Trade where show _ = "Trade"
main = withFile "inFile.txt" ReadMode $ \handle -> runEffect $
for (decodeHandle handle) $ \trade -> do
lift $ print (trade :: Trade)
-- do more with the parsed trade
デコードされた取引をループして処理するために使用for
できます。または、必要に応じてパイプ構成を使用できます。
main = withFile "inFile.txt" ReadMode $ \handle -> runEffect $
decodeHandle handle >-> P.print
これは怠惰で、実際に必要な数の取引のみをデコードします。したがってtake
、デコーダーとプリンターの間に を挿入すると、要求された数の取引を処理するために必要なだけの入力のみが読み取られます。
main = withFile "inFile.txt" ReadMode $ \handle -> runEffect $
for (decodeHandle handle >-> P.take 4) $ \trade -> do
... -- This will only process the first 4 trades
-- or using purely pipe composition:
main = withFile "inFile.txt" ReadMode $ \handle -> runEffect $
decodeHandle handle >-> P.take 4 >-> P.print