2016-02-01 16 views
8

は、私は自分のsum機能を書き込むことによってpipesパッケージを学ぶしようとしていると私は困惑して取得しています。私は(それはそれは些細な作りsumfoldやその他の機能を持っているので)Pipes.Preludeからユーティリティ関数を使用しないのが好きとだけPipes.Tutorialに記載された情報を使用すると思います。チュートリアルでは、Proxyのコンストラクタについて話しませんが、私はsumfoldのソースで見れば、それは、これらのコンストラクタを使用して、私はこれらの低レベルの詳細の知識がなくても、私のsum機能を書き込むことができるだろうか。Haskell Pipes "sum"関数の記述方法は?

私は、この機能は限り利用可能な値があるような値で撮影を続行することができるだろうかとの用語に来てトラブルを抱えて、その後、何らかの形でユーザーにその合計を返しています。私はタイプのようになり推測:

sum' :: Monad m => Consumer Int m Int 

それはもうあるまで、この関数は、最終的な合計を返し、その後、値を消費しない可能性があるため、これは仕事ができる私に表示されます。しかし、Pipes.Prelude内の関数ではなく、次のシグネチャがあり

mysum <- runEffect $ inputs >-> sum' 

sum :: (Monad m, Num a) => Producer a m() -> m a 

だから私はこれが私の最初のハードルであると思います私はこのようにそれを使用します。 sum関数が>->を使用して接続するのに対して、なぜ引数としてProducerを受け取るのですか?


はFYI私はdanidiazからの回答後、次になってしまった:

sum' = go 0 
    where 
    go n p = next p >>= \x -> case x of 
     Left _  -> return n 
     Right (_, p') -> go (n + 1) p' 
+0

は 'パイプにsum' * *は数字を生成し、モナドアクションでそれらをまとめて何かを取る...アイデアは非常に似ていますあなたがそれについて考えるならば - パッケージは、細部を気にする必要はなく、与えられたプリミティブの 'fold 'と残りの部分を使うように設計されています; – Carsten

答えて

5

Consumersは、彼らが何ができるかで、実際には非常に限られています。彼らは、部分が用結果値を提供しなければならないものであること(例えば、上流Producer用)の入力端(pipes-parse、そのために異なる技術を使用する)とするとき、パイプライン停止の他の部分を検出することができませんパイプライン。したがって、合計をConsumerの戻り値に入れることは一般的には機能しません。

いくつかの選択肢があります:

  • Producer内部を直接扱う、または多分nextなどの補助機能を使用する関数を実装します。 foldlパッケージからFoldのように、「よりスマートな」消費者にProducerデータを供給することができ、このタイプのアダプタがあります。

  • はアキュムレータとしてSum IntモノイドとベースモナドとしてWriterTを使用し、Consumerを使用してください、代わりConsumerの戻り値に合計を置きます。そうすれば、最初にProducerが停止しても、ライターを実行してアキュムレータに到達することはできますが、このソリューションは効率が悪い可能性があります。WriterTアプローチの

例コード:うまく

import Data.Monoid 
import Control.Monad 
import Control.Monad.Trans.Writer 
import Pipes 

producer :: Monad m => Producer Int m() 
producer = mapM_ yield [1..10] 

summator :: Monad n => Consumer Int (WriterT (Sum Int) n)() 
summator = forever $ await >>= lift . tell . Sum 

main :: IO() 
main = do 
    Sum r <- execWriterT . runEffect $ producer >-> summator 
    print r 
+0

"入力の終わりを検出できませんでした "私は行方不明でした。どうもありがとう。 – Ana

関連する問題