顺序 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 案例/错误处理 的相关文章

  • 如何处理“恐慌:不可能的事情发生了”并在 Haskell 中继续

    我有以下代码 它使用 GHC API 加载模块并获取表达式的类型 typeObjects String gt String gt IO Type typeObjects modules objects do defaultErrorHand
  • 为什么 exceptT 没有 MonadMask 实例?

    爱德华 克梅特例外情况图书馆不提供单子掩码 https www stackage org haddock lts 7 18 exceptions 0 8 3 Control Monad Catch html t MonadMask实例为Ex
  • 管道中缺少 ResourceT 实例

    我在尝试使用时遇到奇怪的错误ResourceT http hackage haskell org package conduit 1 0 9 1 docs Data Conduit html t 3aResourceT来自管道 1 0 9
  • Haskell 排列库函数 - 请澄清一下?

    这是代码permutationsHaskell 中的函数Data List module permutations a gt a permutations xs0 xs0 perms xs0 where perms perms t ts i
  • 如何避免编写这种类型的 Haskell 样板代码

    我经常遇到这种情况 这很烦人 假设我有一个 sum 类型 它可以保存一个实例x或一堆其他无关的事情x data Foo x X x Y Int Z String other constructors not involving x 要声明
  • 为什么 Haskell 中的点是从右向左排列的?

    如果我们有两个函数 f and g 然后在哈斯克尔h f g相当于h x f g x IE 这些函数从右到左应用于输入 有什么根本原因可以解释为什么它是从右到左 而不是从左到右吗 IE 他们为什么不做h f g相当于h x g f x 反而
  • Haskell 类型定义,=> 等

    我正在使用 Learn You a Haskell 来学习 Haskell 第 54 页上有一个 像这样执行 take Num i Ord i gt i gt a gt a take n n lt 0 take take n x xs x
  • Haskell:GHC 无法推断类型。由类型签名错误绑定的刚性类型变量

    我看过几篇主题相似的帖子 但它们并不能真正帮助我解决我的问题 所以我才敢重复 现在我有一个带有签名的函数 run Expr query gt RethinkDBHandle gt query gt IO JSON 这是一个数据库查询运行函数
  • Haskell 中的多态函数作为参数

    我有一个带有两个构造函数的 ADT 一个包裹着一个Double和一个包裹着Integer 我想创建一个函数 它采用一元函数Numtypeclass 并返回一个函数 该函数将该一元函数应用于我的 ADT 的内容 我试过这个 data X Y
  • 如何构造 Network.HTTP.Conduit.Request 对象?

    试图构建一个Request with 网络 HTTP 管道 http hackage haskell org packages archive http conduit 1 1 0 1 doc html Network HTTP Condu
  • haskell复制目录的方法是什么

    我发现自己用 Haskell 编写越来越多的脚本 但在某些情况下 我真的不确定如何 正确 地做到这一点 例如递归地复制目录 a la unixcp r 由于我主要使用 Linux 和 Mac OS 所以我通常会作弊 import Syste
  • 如何计算函数被调用的次数,FP方式

    我目前正在通过SICP http mitpress mit edu sicp 与哈斯克尔 练习 1 15 询问一个函数被调用了多少次 这个想法可能是您应该使用替换方法 但我想知道如何在代码中执行此操作 在命令式语言中 我们可以保留一个全局变
  • 如何从有向无环图导出FRP?

    我目前正在研究我的下一个项目 目前处于预规划阶段 因此这个问题只是为了了解现有技术的概述 Setup 我有一个具有多个输入和输出的有向无环图 DAG 现在考虑人工神经网络 处理这种结构的常见方法是在每个 时间 步骤上处理整个网络 我相信这是
  • 了解函数类型

    我在尝试理解 Haskell 如何确定函数类型时感到有点困惑 这是一个例子 boolFcn x y x 3 y 4 当我检查上述函数的类型时 它给出了结果 Num a1 Num a Eq a1 Eq a gt a gt a1 gt Bool
  • Haskell 如何将整数文字转换为不同类型?

    我有以下匿名函数 Exercises gt g Sum n gt Sum n 1 我这样使用它 Exercises gt g Sum 56 Sum getSum 55 Exercises gt g 56 Sum getSum 55 第二个例
  • 为连续可测量的现象创建行为

    我想创建一个Behavior t a从一个IO a 其预期语义是每次行为发生时都会运行 IO 操作sampled language FlexibleContexts import Reflex Dom import Control Mona
  • 优化计算 200 万以下所有素数总和的 Haskell 代码

    欧拉计划中的问题 10 我在那里看到了一些讨论 但仅限于 C 我用下面的代码来计算 print sum sieve 2 2000000 where sieve sieve x xs x sieve filter 0 mod x xs 需要很
  • 数据记录的类约束

    我有一个data type data BuildException a KillBuild JobID a Stage FailBuild JobID a Stage CancelBuild JobID a Stage StopBuild
  • 当您包含导入 Gloss 的项目时,“stack ghci”会失败

    如果您在 Stack 项目中导入 Gloss 并使用stack ghci 您会收到以下错误 GHCi version 7 10 2 http www haskell org ghc for help
  • 如何在 Haskell 中编写 MST 算法(Prim 或 Kruskal)?

    我可以用 C 或 Java 编写 Prim 和 Kruskal 算法来查找最小生成树 但我想知道如何在 Haskell 中以 O mlogm 或 O mlogn 实现它们 纯函数式程序更好 多谢 正如斯文宁森所说 优先搜索队列 http h

随机推荐

  • 这段 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之前 我想在这里举一个更清楚的例子 如何处理必须按顺序检