如何在涉及Either和IO的代码中使用fmap / bind而不是case?

时间:2017-02-23 18:14:13

标签: haskell

在下面的代码中,case-expression看起来类似于Either的绑定实现。

doConfirmation :: Registration -> IO (Either Text ())
findRegistration :: Text -> DbData -> Either Text Registration

dbData <- readTVarIO db
case findRegistration rid dbData of
  Right r -> doConfirmation r
  Left err -> return $ Left err

我如何编写它以利用它而不是在出现错误时明确return Left

1 个答案:

答案 0 :(得分:1)

在关注评论并阅读Haskell中的异常处理后,我做了以下事情:

我将可能失败的非IO函数从Either Text a更改为Either MyException a

然后我将IO函数从IO (Either e a)更改为简单IO a,因为IO中存在例外情况。

然后我还添加了raise辅助函数。

这使代码变得干净整洁。见下文:

raise :: Exception e => Either e a -> IO a
raise = either throwIO return

doConfirmation :: Registration -> IO ()
findRegistration :: Text -> DbData -> Either RegistrationException Registration

readTVarIO
>>= raise . findRegistration rid
>>= doConfirmation

可能这可以进一步改进,但现在我对结果感到满意