[英]Reusing sinkFile with Haskell Conduit
我想將一個照片列表發送到接收器以將其保存在磁盤上。 每個Photo結構都包含lazy ByteString類型的content
字段。
基本上我想做那樣的事情:
CL.sourceList photos $$ sinkPhotos
我想在我的接收器中重用CB.sinkFile
,因為如果我理解正確,它會進行錯誤管理。 這是我到目前為止的嘗試:
mkFilePath :: Photo -> FilePath
mkFilePath photo = last $ splitOn "/" (url photo)
sinkPhotos :: Sink Photo IO ()
sinkPhotos = do
mphoto <- await
case mphoto of
Nothing -> return ()
Just photo -> do
yield ct =$ CB.sinkFile fp
sinkPhotos
where fp = mkFilePath photo
ct = BL.toStrict $ content photo
它失敗了:
src/Screepy/Main.hs:30:23:
No instance for (MonadResource IO)
arising from a use of `CB.sinkFile'
Possible fix: add an instance declaration for (MonadResource IO)
In the second argument of `(=$)', namely `CB.sinkFile fp'
In a stmt of a 'do' block: yield ct =$ CB.sinkFile fp
In the expression:
do { yield ct =$ CB.sinkFile fp;
sinkPhotos }
sinkFile
包裝在結構上而不是直接用於ByteString
? ByteString
創建Source
? 我不確定我是否在回答你提出的所有問題。 我只會解決類型問題:錯誤只是由於您提供的簽名而引起的。 這不行嗎?
sinkPhotos :: MonadResource m => Sink Photo m ()
sinkPhotos = do
mphoto <- await
case mphoto of
Nothing -> return ()
Just photo -> do
yield ct =$ CB.sinkFile fp
sinkPhotos
where fp = mkFilePath photo
ct = BL.toStrict $ content photo
現在只是找到使用runResourceT
的正確位置的問題,不是嗎? 查詢ghci
我們看到:
>>> let photos = [] :: [Photo]
>>> :t CL.sourceList photos $$ sinkPhotos
CL.sourceList photos $$ sinkPhotos :: MonadResource m => m ()
>>> :t runResourceT $ CL.sourceList photos $$ sinkPhotos
runResourceT $ CL.sourceList photos $$ sinkPhotos
:: (MonadThrow m, MonadBaseControl IO m, Control.Monad.IO.Class.MonadIO m) => m ()
>>> :t runResourceT $ CL.sourceList photos $$ sinkPhotos :: IO ()
runResourceT $ CL.sourceList photos $$ sinkPhotos :: IO ()
所以給出一個照片列表,你可以寫
main = runResourceT $ CL.sourceList photos $$ sinkPhotos
編輯:順便說一句,如果你使用類型,ghci中的類型查詢會給出更清晰的結果
sinkPhotos :: Sink Photo (ResourceT IO) ()
雖然你可能有理由允許其他可能性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.