2012-07-04 66 views
4

我決定嘗試並獲得對管道的處理,並且我認爲我做得很好,但是當我嘗試使用導管4製作這個簡單源代碼時,我得到一個無限循環,不明白爲什麼。這是簡化的,原始版本將創建一個臨時文件名並通過yield返回。這只是返回一個()。無限循環源代碼與導管

import Control.Monad.IO.Class 

import Data.Conduit 
import Data.Conduit.List as CL 

tempfiles :: MonadIO m => Source m() 
tempfiles = loop 
    where 
    loop = do 
     x <- liftIO $ print "tempfile" 
     yield x 
     loop 

如果我運行:

runResourceT $ (tempfiles $$ CL.take 5) 

我得到一個無限循環。爲什麼它不運行五次並給我一個五()s的列表?

+0

Minor nitpick:爲什麼'tempfiles = loop where loop = do ... loop'?爲什麼不只是'tempfiles =做... tempfiles'? –

+0

因爲System.Posix.Temp中的mkstemp函數需要一個參數,所以tempfiles本身需要一個參數,但由於我正在遞歸併且該參數沒有改變,而不是再次傳遞它,所以我只做了一個循環函數來完成遞歸與持續重用在頂層傳入的參數。 –

+0

最終結果是這樣的:https://gist.github.com/3051620老實說,這真是太酷了。本質上是一個無限的懶惰臨時文件生成器。這個圖書館很有趣。 –

回答

4

在導管0.4中,收益不執行自動終止。這是0.5版本的一個重要變化;您的代碼在那裏按預期工作。

+0

嗯,我正在等待http-conduit,但我想這是一個很好的理由現在更新。謝謝。 –