顺序 monad 中优雅的 haskell 案例/错误处理

2024-01-10

因为我过于简单化了其他问题 https://stackoverflow.com/questions/13251388/elegant-haskell-case-error-handling之前,我想在这里举一个更清楚的例子。

如何处理必须按顺序检查某些条件而不嵌套多个情况的情况?对于“顺序方式”,我的意思是获取一个值(例如从标准输入),在特定条件下检查该值,并根据结果获取另一个值,依此类推。

Example:

sequen :: IO String
sequen = do
  a <- getLine
  case a of
    "hi" -> do
      putStrLn "hello!"
      b <- getLine
      case b of
        "how are you?" -> do
          putStrLn "fine, thanks"
          return "nice conversation"
        _ -> return "error 2"
    _ -> return "error 1"

我知道有更好的方法来编写这样的聊天机器人,它应该只是展示问题的顺序性质。正如您所看到的,对于每个嵌套情况,代码也会缩进得更深。

有没有办法更好地构造这样的代码?我正在考虑在一个地方处理“错误”并描述“成功路径”,而不将错误处理分布在整个地方。


当然。这正是EitherT是为.你可以从Control.Monad.Trans.Either in the eitherT包裹。

import Control.Monad.Trans.Class
import Control.Monad.Trans.Either

main = do
    e <- runEitherT $ do
        a <- lift getLine
        case a of
            "hi" -> lift $ putStrLn "hello!"
            _    -> left 1
        b <- lift getLine
        case b of
            "how are you?" -> lift $ putStrLn "fine, thanks!"
            _              -> left 2
        return "nice conversation"
    case e of
        Left  n   -> putStrLn $ "Error - Code: " ++ show n
        Right str -> putStrLn $ "Success - String: " ++ str

EitherT每当遇到以下情况时中止当前代码块left语句,人们通常用它来指示错误情况。

内部块的类型是EitherT Int IO String。当你runEitherT它,你得到IO (Either Int String). The Left类型对应于失败的情况leftRightvalue 表示它成功到达块的末尾。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

顺序 monad 中优雅的 haskell 案例/错误处理 的相关文章

随机推荐

  • 这段 JavaScript 代码是什么意思?

    var myval function 我不明白 function 含义甚至其他代码 你所拥有的是 自调用匿名函数 您首先通过在函数本身周围添加括号来创建函数表达式 只是为了写 function 在这种情况下不起作用 因为这将定义一个函数声明
  • Magento 扩展 404 错误

    我很难过 我有一个自定义扩展 可以在 Mac Leopard 本地完美运行 但是在将实时推送到主机 Centos Linux 后 当我尝试调用前端路由器时 出现 Magento 404 错误 例如这个网址 domain shop index
  • PHP 如何获取带有类和名称空间路径的方法名称作为字符串?

    我真的很讨厌写这个问题 因为我是一种 研究人员 而且 我总是能找到我正在寻找的东西 但这一个让我很烦恼 我在任何地方都找不到答案 所以 事情是这样的 正如标题所示 我需要获取一个方法名称 其中尾随类和命名空间路径作为字符串 我的意思是这样的
  • 关于android加速度计onSensorChanged的信息

    我正在尝试在android平台上编写一个体感游戏 我将整个运动检测算法包含到 onSensorChanged 函数中 问题在于该函数根据输入执行不同的时间 我对函数如何执行和调用有一些疑问 1 如果我的函数执行很长时间 并且发生了 2 个
  • 使用 Julia 中的 Images 导出图像

    假设我有一个m by n by 3的数组Uint8它表示一个图像 其中假定使用 RGB 色彩空间 我想使用以下命令将其导出为每像素 24 位 PNG 图像Images包裹 我怎样才能做到这一点 我天真地尝试申请imwrite到随机生成的原始
  • 附加 pandas 数据框自动转换为 float 但需要 int

    如何让 pandas 附加一个整数并保留整数数据类型 我意识到我可以在输入数据后将 df test astype int 添加到整个列 但如果我可以在附加数据时执行此操作 那么这似乎是一个更好的方法 这是一个示例 from bitstrin
  • 即使包含当前脚本,也要获取当前脚本的 URL?

    我有一个 PHP 脚本 需要知道它的 URL 即使它包含在另一个脚本中 我试过了 SERVER REQUEST URI 但这不会将 URI 返回到我的脚本 而是将 URI 返回到包括脚本 我也尝试过 dirname FILE 但我似乎无法将
  • 通过 gcloud 命令行工具触发特定 git 提交的构建

    我遇到的所有示例均采用以下格式 gcloud container builds submit config cloudbuild yaml 手册页内容如下 SOURCE The source directory on local disk
  • 自定义按钮的核心图形与图像

    我什么时候应该使用核心图形而不是图像来制作自定义 UIButton 核心显卡速度更快吗 除了分辨率独立之外 还有其他主要好处吗 核心显卡的优点 绘制按钮的代码可能比图像文件小 允许动态修改 轻微更改 而无需添加完整的第二个图像 正如您提到的
  • 在 Rust 中多次使用同一个迭代器

    编者注 此代码示例来自 1 0 之前的 Rust 版本 当时实现了许多迭代器Copy 此代码的更新版本会产生不同的错误 但答案仍然包含有价值的信息 我正在尝试编写一个函数来将字符串拆分为字母和数字块 例如 test123test 会变成 t
  • Haskell 编译器如何决定是在堆上分配还是在堆栈上分配?

    Haskell 不具有显式内存管理功能 并且所有对象都是按值传递的 因此也没有明显的引用计数或垃圾收集 Haskell 编译器通常如何决定是为给定变量生成在堆栈上分配的代码还是在堆上分配的代码 它是否会在堆或堆栈上为同一函数在不同的调用站点
  • 如何使用 webmock 正则表达式匹配器?

    如何匹配 URL 例如 http www example com foo id bar http www example com foo 1 bar http www example com foo 999 bar 存根请求 帖子 www
  • 使用 onmousedown 来获取您刚刚按下鼠标的元素的 ID?

    这可能吗 我正在尝试为 onmousedown 编写一个函数 它将返回您刚刚单击的元素的 ID 以便稍后在不同的 div 中重新创建该元素时使用 您可以使用事件委托 http www sitepoint com blogs 2008 07
  • 从 TFRecordDataset 获取数据集作为 numpy 数组

    我正在使用新的tf data API为 CIFAR10 数据集创建迭代器 我正在读取两个数据 tfrecord文件 一个保存训练数据 train tfrecords 另一个保存测试数据 test tfrecords 这一切都很好 然而 在某
  • axios:如何拦截并响应axios请求

    有没有一种方法不仅可以拦截 axios 请求 还可以在发送之前对其进行响应 就像这样 从浏览器发送请求并从浏览器响应它 阻止它发送请求 我知道我可以使用axios interceptors在请求和响应发送并返回到组件之前拦截请求和响应 我知
  • 截断至小数点后两位,不四舍五入

    无法找到或找出适用于 Dart 的解决方案 我已经尝试过 1 toStringAsFixed 本轮2 double parse number toStringAsFixed 本轮3 num num 0 01 本轮 我在 SO 上找到了一些解
  • 如何在 Mac OS Lion 中为 Titanium 配置 Android SDK?

    I have successfully installed Titanium Studio SDK Version 1 7 5 Now I have downloaded Android SDK from http developer an
  • BaseController 中的 Get/Set HttpContext Session 方法与模拟 HttpContextBase 来创建 Get/Set 方法

    我在 BaseController 类中创建了 Get Set HttpContext Session 方法 还模拟了 HttpContextBase 并创建了 Get Set 方法 这是最好的使用方法 HomeController Bas
  • 如何轻松维护跨文件的 JavaScript 库开发环境

    我一直在开发一个新的 JavaScript 应用程序 该应用程序的规模正在迅速增长 我的整个 JavaScript 应用程序已封装在单个文件中的单个函数中 如下所示 function var uniqueApplication window
  • 顺序 monad 中优雅的 haskell 案例/错误处理

    因为我过于简单化了其他问题 https stackoverflow com questions 13251388 elegant haskell case error handling之前 我想在这里举一个更清楚的例子 如何处理必须按顺序检