haskell - 无法从 Conduit 中的错误中恢复

标签 haskell conduit

我试图了解如何捕获管道内引发的错误。我相信通过在管道上应用 catchC,我可以生成一个新的管道,该管道将在发生故障时重新运行。

在下面的示例中,我们有一个源,根据 bool 值,该源将抛出自定义虚拟异常。最初,该 bool 值会导致抛出该异常,但是 catchC 内的处理程序会生成一个新的管道,该管道应表现出相反的行为(产生从 1 到 10 的数字)

{-# LANGUAGE DeriveDataTypeable #-}

module Main where

import Data.Conduit
import qualified Data.Conduit.List as CL
import Control.Monad.IO.Class
import Control.Exception
import Data.Typeable

data MyException = MyException String
    deriving (Show, Typeable)

instance Exception MyException where

listAsStream :: Bool -> Source IO Int
listAsStream val =  if val then CL.sourceList [1..10] else throw $ MyException "Value"

conduitWhatever :: Sink Int IO ()
conduitWhatever = awaitForever $ liftIO . print

main :: IO ()
main = catchC (listAsStream False) handler $$ conduitWhatever

handler :: MyException -> Source IO Int
handler _= catchC (listAsStream True) handler

我很确定我误解了 catchC 的工作原理。谁能解释一下我做错了什么?

非常感谢!

最佳答案

您对catchC的使用是正确的;问题在于使用了 throw ,它引入了不精确的异常,而不是正确的 IO 异常。如果您改为使用:

liftIO $ throwIO $ MyException "Value"

您的程序按预期工作。

关于haskell - 无法从 Conduit 中的错误中恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28058280/

相关文章:

haskell - 是否可以在主函数之外(在 haskell 中)使用 writeFile?

haskell - 为什么 Monoidal 和 Applicative 定律告诉我们同样的事情?

haskell - 枚举器与导管的优缺点是什么?管道?

haskell - 无限读取文件

exception - 与 aeson/attoparsec 进行管道,一旦源没有更多数据,如何无异常地干净退出

haskell - Haskell 中 (1 2) 的类型是什么?

haskell - 有用于文本的 Haskell readMaybe 函数吗?

haskell - 您将如何遍历目录并对所有文件执行某些功能并以内存有效的方式组合输出?

haskell - 组合两个水槽的首选方式是什么?

haskell - Haskell 中命名字段的令人惊讶的类型推断