私はこれを使用zipSinks :: Monad m => Sink i m r -> Sink i m r' -> Sink i m (r, r')
しましたが、非推奨と見なされます。
2 に答える
編集
これを検討した結果、現在のバージョンの Data.Conduit では不可能だと思います。パイプはカテゴリではないため&&&
、問題外です。そして、上流から結果を引き出し、それらを両方のシンクに段階的に供給し、最初のシンクが終了したときに短絡する方法は考えられません。(私はこのようにショートサーキットするとは思いませんがData.Conduit.Util.zipSinks
、それは非常に望ましいことのようです.) もちろん、両方のシンクでパターンマッチすることを除いて (zipSinks
パッケージのように)、しかしそれが私たちがしようとしていることです.ここは避ける。
とはいえ、ここで私が間違っていることが証明されたいと思っています。
きれいではありませんが、ある種の明白な方法でこれを行うことができます。
最初のインポート:
module Main where
import Control.Monad.Trans
import Data.Conduit
import qualified Data.Conduit.Binary as CB
import qualified Data.Conduit.List as CL
import qualified Data.Conduit.Text as CT
import qualified Data.Conduit.Util as CU
import Data.Maybe
import Data.Text (unpack)
今すぐzipSinks
。基本的に、上流から入力をプルして、それを各子シンクに個別に送信するシンクを作成します。この場合、私はこれを行っCL.sourceList
ていました。await
を返す場合Nothing
、maybeToList
空のリストを返すため、子シンクも入力なしで実行されます。最後に、各子シンクの出力がタプルに供給されます。
zipSinks :: Monad m => Sink i m r -> Sink i m r' -> Sink i m (r, r')
zipSinks s1 s2 = do
l <- fmap maybeToList await
o1 <- lift $ CL.sourceList l $$ s1
o2 <- lift $ CL.sourceList l $$ s2
return (o1, o2)
の使用例をいくつか示しzipSinks
ます。内部と外部の両方で正常に動作するように見えます。私が行ったいくつかのテストでは、出力は、古い を使用して作成されIO
た の出力と一致します。zipped'
zipSinks
doubleHead :: Monad m => Sink Int m (Maybe Int)
doubleHead = await >>= return . fmap (2*)
-- old version
zipped' :: Monad m => Sink Int m (Maybe Int, Maybe Int)
zipped' = CU.zipSinks CL.head doubleHead
-- new version
zipped :: Monad m => Sink Int m (Maybe Int, Maybe Int)
zipped = zipSinks CL.head doubleHead
fromList = CL.sourceList [7, 8, 9] $$ zipped
-- (Just 7, Just 14)
fromFile :: String -> IO (Maybe Int, Maybe Int)
fromFile filename = runResourceT $
CB.sourceFile filename
$= CB.lines
$= CT.decode CT.utf8
$= CL.map (read . unpack)
$$ zipped
-- for a file with the lines:
--
-- 1
-- 2
-- 3
--
-- returns (Just 1, Just 2)
((パッケージはconduit-0.5.2.3です。モジュール全体は後方互換性のためだけです。))
[編集]
したがって、型が正しいにもかかわらず、私の単純なモナド推測 (以下を参照) は間違っているようです。今、答えは次のようにしか推測できません。
置き換え機能は、すべての Pipe/Conduit および同様の概念とライブラリと同様に、まだ開発中です。
次の API がこの問題を解決するのを待ち、zipSink
それまで使用します。(単に置き場所を間違えたのかもしれません。)
[ /編集]
私はこのパッケージにあまり詳しくありませんが、これとまったく同じではないでしょうか?
zipSinks :: Monad m => Sink i m r -> Sink i m r' -> Sink i m (r, r')
zipSinks s1 s2 = (,) <$> s1 <*> s2
zipSinks :: Monad sink => sink r -> sink r' -> sink (r, r')
zipSinks s1 s2 = liftM2 (,) s1 s2