Как правильно обернуть трубопровод 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
было бы неплохо вырваться из конвейера и вернуть сообщение об ошибке наверх. Я прочитал этот сообщение в блоге но еще недостаточно хорошо это понял, чтобы применить его к каналу (который также имеет сложную сигнатуру типа). Я хотел бы применить предложенный подход здесь для канала - кажется, что EitherT
, предложенный в подходе, теперь включен в ExceptT
.