2

を使用してファイルから読み取っていますsourceFileが、処理操作にランダム性を導入する必要もあります。私が信じている最善のアプローチは、次のタイプのプロデューサーを持つことです

Producer m (StdGen, ByteString)

ここで、StdGen を使用して乱数を生成します。

プロデューサーが sourceFile のタスクを実行するだけでなく、データをダウンストリームに送信するたびに生成する新しいシードを生成することを意図しています。

zipSink私の問題は、シンクのようなソースコンバイナーがないように見えることです。Conduit Overviewを読むと、 a を a のSource中に埋め込むことができることが示唆されているようですがConduit、例ではそれがどのように行われているかわかりません。

Producer2 つ以上の IO ソースを 1 つの/に融合する例を誰か提供できますSourceか?

編集 :

例:

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE OverloadedStrings #-}

import System.Random (StdGen(..), split, newStdGen, randomR)
import ClassyPrelude.Conduit as Prelude
import Control.Monad.Trans.Resource (runResourceT, ResourceT(..))
import qualified Data.ByteString as BS

-- generate a infinite source of random number seeds
sourceStdGen :: MonadIO m => Source m StdGen
sourceStdGen = do
    g <- liftIO newStdGen
    loop g
    where loop gin = do
            let g' = fst (split gin)
            yield gin
            loop g'

-- combine the sources into one
sourceInput :: (MonadResource m, MonadIO m) => FilePath -> Source m (StdGen, ByteString)
sourceInput fp = getZipSource $ (,)
    <$> ZipSource sourceStdGen
    <*> ZipSource (sourceFile fp)

-- a simple conduit, which generates a random number from provide StdGen
-- and append the byte value to the provided ByteString
simpleConduit :: Conduit (StdGen, ByteString) (ResourceT IO) ByteString
simpleConduit = mapC process 

process :: (StdGen, ByteString) -> ByteString
process (g, bs) =
    let rnd = fst $ randomR (40,50) g
    in bs ++ pack [rnd]

main :: IO ()
main = do
    runResourceT $ sourceInput "test.txt" $$ simpleConduit =$ sinkFile "output.txt"

したがって、この例では、入力ファイルの内容を取得して出力ファイルに書き込み、ファイルの末尾に 40 ~ 50 のランダムな ASCII 値を追加します。(理由は聞かないで)

4

2 に答える 2

2

IOモナドでそれを行い、結果をプロデューサーに持ち上げることができます。

do (i, newSeed) <- next currentSeed
   b <- generateByteStringFromRandomNumber i
   return (b, newSeed)

その IO アクションは、単純なリフトで適切なコンジットに持ち上げることができます。

-- assuming the above action is named x and takes the current seed as an argument
-- the corresponding producer/source is:
lift $ x currentSeed
于 2014-04-27T15:31:02.990 に答える