2017-06-02 15 views
2

を理解する:与えられ、コンジットを使用して `conduit`出力

Prelude> :t (yieldMany [1..10] .| mapC show .| mapC print .| sinkList) 
(yieldMany [1..10] .| mapC show .| mapC print .| sinkList) 
    :: Monad m => ConduitM a c m [IO()] 

はなぜ任意の出力は記録されませんか?

Prelude> runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList 
Prelude> 

私の期待値が印刷される、[1..10]のストリームについては、その各要素のString、すなわちshowました。

この出力を説明してください。

+2

IIRCでは、最近のCRの質問にも同様の問題がありました。このような問題が発生した場合は、アノテーションタイプの適切なソースファイルを使用してください。 'IO'を使うとGHCiが少し違うことに気付くでしょう。タイプアノテーションを追加すると、GHCは 'runConduit $ ...'の結果が 'IO [()]'ではなく 'IO [IO()]'であることを叫ぶでしょう。 – Zeta

答えて

6

導管の結果はモナドでIO()のリストではなく、単一IO()です:あなたはmIOに設定しても

Prelude Conduit> :t runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList 
runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList 
    :: Monad m => m [IO()] 

、あなたはしない、結果としてIO [IO()]に終わります[IO()]にはShowインスタンスがないため、表示されます。あなたは>>= sequence_を追加した場合ということで解決できます。

(runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList) >>= sequence_ 

しかし、本当の問題は、あなたがmapC print代わりのmapMC printを使用することである:

Prelude Conduit> :t mapC 
mapC :: Monad m => (a -> b) -> Conduit a m b 
Prelude Conduit> :t mapMC 
mapMC :: Monad m => (a -> m b) -> Conduit a m b 

あなたがmapC printを使用する場合は、あなたがConduit a m (IO())で終わります。 mapMC printを使用すると、最終的にConduit a IO()になります。後者はmからIOに設定されますが、最初はそうではありません。

だから、モナドの関数の正しいコンビネータを使用する:あなたが期待する結果を得ていない場合

runConduit $ yieldMany [1..10] .| mapC show .| mapMC print .| sinkNull 
--            ^

また、GHCiの中itの種類を確認してください。

関連する問題