我正在尝试从WriterT包装的IO生成无限的懒惰值流。我正在使用管道来使用此流并将其写入文件。我很清楚其绑定运算符中IO的严格性,那么如何在那里懒惰地生成这个流呢?
如果不可能,我应该尝试改为懒惰的ST吗?
import Data.Conduit
import Control.Monad.Writer
import Data.DList as DL
type Stream = WriterT (DL.DList String) IO ()
generator :: Stream
generator = do
tell $ DL.singleton "something"
generator
runStream :: Stream -> IO ()
runStream s = runResourceT $ stream s
where stream s = sourceStream s $$ sinkStream -- sinkStream just writes to a file
sourceStream s = do w <- liftIO $ execWriterT s
CL.sourceList (DL.toList w)
答案 0 :(得分:1)
看到没有人给出完整答案,我会将我的评论转换成一个。 conduit
的一大优势是它可以使我们免于使用懒惰的IO!使用复杂的WriterT
违背了这个想法。相反,我们应该generator
一个Source
,然后使用文件Sink
插入它:
import Control.Monad
import Data.Conduit
import Data.Conduit.Binary
import qualified Data.ByteString.Char8 as BS
generator :: Monad m => Source m String
generator = replicateM_ 3 (yield "something\n")
-- or `forever (...)` if you want an infinite loop
-- Reads Strings, converts them to ByteStrings and writes
-- to a file.
sinkStream :: MonadResource m => FilePath -> Sink String m ()
sinkStream file = mapInput BS.pack (const Nothing) (sinkFile file)
main :: IO ()
main = runResourceT (generator $$ sinkStream "/tmp/output.txt")