ExceptT
にコンジットをラップする良い方法はありますか?このアプローチでは、エラーが発生したときに処理を停止し、エラーメッセージを抽出する必要があります。ここではおもちゃのコードは、エラー処理なしである - それはただ静かに停止します。コンジットをExceptTに入れよう
import Data.Conduit as C
import Data.ByteString as BS
import Control.Monad
import Control.Monad.IO.Class
import Data.Text as T
-- just a dummy processing to simulate errors
process :: BS.ByteString -> Either (Int,T.Text) BS.ByteString
process inp = if (BS.null inp) then Left $ (1,"Empty input") else Right inp
-- silent processing - stops on error but doesn't tell us what it is
sink :: MonadIO m => Consumer BS.ByteString m()
sink = do
bs <- await
case bs of
Just val -> do
let msg = process val
case msg of
Left _ -> return()
Right x -> (liftIO $ return x) >> sink
Nothing -> return()
私たちは以下のようなものにsink
の型シグネチャを変更することができますどのように?
sink :: MonadIO m => ExceptT e m (Consumer BS.ByteString m())
Left
の場合は、パイプラインから抜け出すのはいいだろう、とトップにエラーメッセージを返します。 私はこれをblog postと読んでいますが、コンジット(これも複雑な型名を持っています)にそれを適用するには十分に理解していません。私は導管に提案されたアプローチhereを適用したいと思っています - それはEitherT
のアプローチで提案されているようです今ExceptT
によって包含されています。
ありがとうございました。私はexceptTをよく知っていますが、 'ExceptT Err(Consumer ByteString m())()'のようなシグネチャをどうやって取得するかはまだ分かりません。パイプラインレベルの上でエラー処理をしようとしているので、どちらかに行くのが良いかどうかは分かりません。このようなものは、 '' $$ 'のようなものです。停止して「左」エラーを返します。パイプの場合は、私の質問にリンクされているポストに書かれているように、それはExceptT e(Pipe a b m)rです。 –
Sal
「Sink」で更新された回答。実際には、コンシューマがその型パラメータの1つで普遍的に修飾されているため、 'ExceptT Err(Consumer ...) 'を作成することはできません。 'パイプ'はそれほど定義されていません - 'シンク'に近いです。だから私は 'ExceptT ...シンク...'あなたが探しているものだと思います – ErikR
まあ、私は同じように思った。助けてくれてありがとう。 – Sal