2015-12-13 4 views
8

私は小さなHaskellのPipeを持って、それが実行された回数を出力します:それは最後に処理した後、私は、メッセージをプリントアウトし、潜在的に他のタスクを実行できるようにしたいと思いハスケルパイプで最後のチャンクを検出する方法は?

counterPipe :: Pipe String String IO r 
counterPipe = go 0 
    where 
    go n = do 
     await >>= yield 
     let n' = succ n 
     liftIO $ putStrLn $ "Chunk " ++ show n' 
     go n' 

をチャンク。これをどうやって行うのですか?

答えて

3

これはMaybe StringcounterPipeの入力タイプを変更し、上流管が終了した後、余分なNothingを注入することによって仕事を得ることができた:

import Pipes 
import Pipes.Core (respond) 
import Control.Applicative ((<*)) 

withEOF :: (Monad m) => Proxy a' a b' b m r -> Proxy a' a b' (Maybe b) m r 
withEOF p = for p (respond . Just) <* respond Nothing 

counterPipe :: Pipe (Maybe String) String IO Int 
counterPipe = go 0 
    where 
    go n = do 
     mx <- await 

     case mx of 
      Just x -> do 
       yield x 
       let n' = succ n 
       liftIO $ putStrLn $ "Chunk " ++ show n' 
       go n' 
      Nothing -> do 
       return n 

finishCounter :: Int -> Pipe a b IO() 
finishCounter n = liftIO $ putStrLn $ unwords ["Finished after", show n, "chunks"] 

例ドライバ:

import qualified Pipes.Prelude as P 
main = runEffect $ withEOF P.stdinLn >-> (counterPipe >>= finishCounter) >-> P.stdoutLn 

Iこのパターンは抽象的であるべきだと思います

whileJust :: (Monad m) => Proxy a' a b' b m r -> Proxy a' (Maybe a) b' b m (Maybe r) 

ので、あなたの元counterPipeの定義を変更することなく

withEOF P.stdinLn >-> (whileJust counterPipe >>= maybe (return()) finishCounter) >-> P.stdoutLn 

を書くことができ、 しかし、前にPipesを使用したことはありません(上記の解決策は、タイプと再生タイプを調べるだけでわかりました)ので、私はwhileJustと書いていませんでした(署名はあまりにも一般的ではありません見つけ出す)。

関連する問題