以下是您如何操作pipes
的方法。我真的不知道你是怎麼實現loadMeta
和find
,所以我做的東西了:
import Pipes
find :: Producer FilePath IO()
find = each ["heavy.mp3", "metal.mp3"]
type MetaData = String
loadMeta :: String -> IO MetaData
loadMeta file = return $ "This song is " ++ takeWhile (/= '.') file
loadMetaList :: Pipe FilePath MetaData IO r
loadMetaList = mapM loadMeta
要運行它,我們只是撰寫處理階段就像一個管道和使用runEffect
運行管道:
>>> runEffect $ find >-> loadMetaList >-> stdoutLn
This song is heavy
This song is metal
有幾個關鍵的事情指出:
例如,它會工作,即使我們用文件的無限名單:
>>> import qualified Pipes.Prelude as Pipes
>>> runEffect $ each (cycle ["heavy.mp3", "metal.mp3"]) >-> loadMetaList >-> Pipes.stdoutLn
This song is heavy
This song is metal
This song is heavy
This song is metal
This song is heavy
This song is metal
...
- 它只會計算儘可能必要的。如果我們指定我們只需要三個結果,即使我們提供了無限的文件列表,它也會執行返回兩個結果所需的最小加載量。
例如,我們用take
罐蓋結果的數量:
>>> runEffect $ each (cycle ["heavy.mp3", "metal.mp3"]) >-> loadMetaList >-> Pipes.take 3 >-> Pipes.stdoutLn
This song is heavy
This song is metal
This song is heavy
所以,你問什麼是錯unsafeInterleaveIO
。的unsafeInterleaveIO
主要的限制是,你不能保證當IO
行爲實際發生,這導致了以下常見的陷阱:
Haskell的IO
系統與其他語言相比最大的優點是Haskell完全將評估模型與副作用順序解耦。當你使用懶惰IO
時,你失去了解耦,然後副作用的順序與Haskell的評估模型緊密結合,這是一個倒退的巨大步驟。
這就是爲什麼使用懶惰IO
通常不明智的原因,特別是現在有簡單而優雅的替代品。
如果你想了解更多關於如何使用pipes
安全地實現懶惰IO
,那麼你可以閱讀廣泛的pipes tutorial。
這是[pipes](http://hackage.haskell.org/package/pipes)或[conduit](http://hackage.haskell.org/package/conduit)的好用例。 – ErikR 2013-04-26 19:33:20
起初我以爲這是「loadMetalList」,就像在一堆重金屬的mp3中一樣 – 2013-04-26 19:36:08
其實是加載mp3的元數據 – 2013-04-26 19:57:08