问题标签 [io-monad]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
121 浏览

haskell - haskell 程序的灵活参数数量

我正在使用System.FilePath.Findfilemanip 模块递归地查找我需要处理的所有文件(这里我将仅使用打印到控制台作为要执行的操作,以免混淆事物)。现在,这段代码:

与此通话效果很好

./myprog tet .

在这种情况下,get参数将被忽略(稍后将是输出数据库文件),并递归搜索第二个参数以查找匹配文件。它还允许我指定一个文件,这非常完美!

但是,我希望能够指定

./myprog tet path1 path2 path4 file1

但这当然在模式匹配中失败了:

./myprog tet . .

myprogt:用户错误(myprog.hs:11:9-22 处的 do 表达式中的模式匹配失败)

现在,我如何使这个程序更灵活,以便我可以接受两个以上的参数?

很抱歉问这个问题,但我的 Haskell 知识是有限的,但我在第一个项目中必须做的每件新事情都会增加。

0 投票
3 回答
565 浏览

haskell - 在 haskell 程序中使用返回的 EitherT

我正在尝试在我正在处理的 Haskell 项目中使用“引文解析”包,但在实际代码中使用 EitherT 时遇到了麻烦。我知道它们是单子变换器,我想我理解这意味着什么,但是我似乎无法真正弄清楚如何使用它们。代表我正在尝试做的玩具示例如下:

在这里,resolveEither有类型:

runEitherT $ resolveEither "ref"具有以下类型:

但是,这会产生以下错误:

我不知道如何解决或解决。

任何帮助将不胜感激,特别是从使用角度而不是实现角度处理 monad 转换器的教程的指针。

编辑:

为了反映 dfeuer 和 Christian 对答案的评论,如果我将 main 更改为以下内容,我仍然会遇到错误:

我现在得到的错误是:

我正在编辑我的问题以及发表评论,因为这里的代码格式比在评论中要容易得多。

0 投票
3 回答
159 浏览

haskell - Haskell:对`>>=`运算符的类型感到困惑

我正在学习一些介绍性的 Haskell 材料,目前正在学习 Monads。我从概念上理解>>=运算符的类型:

(Monad m) => m a -> (a -> m b) -> m b.

在这种情况下,我很困惑为什么以下代码有效,即为什么它不会导致类型不匹配:

既然我们知道这一点getLine :: IO String,我会假设它可以与 type 的函数“绑定” String -> IO String。然而putStrLn是不同的类型:putStrLn :: String -> IO ().

那么为什么 Haskell 允许我们使用>>=这两个函数呢?

0 投票
1 回答
292 浏览

haskell - 如何在 IO monad 中使用可变结构

TL;DR:
如何确保randomRIO(from System.Random) 在给定do语句中生成的值的持久性?
如何在 IO Monad 中使用可变结构?

我最初的问题是(非常)错误 - 我正在更新标题,以便未来想要了解在 IO monad 中使用可变结构的读者可以找到这篇文章。

更长的版本:

提醒:这看起来很长,但其中很多只是我概述了如何exercism.io工作。(更新:最后两个代码块是我的代码的旧版本,作为参考包含在内,以防未来的读者希望根据评论/答案跟随代码中的迭代。)

运动概述:

我正在Robot Name(极具指导性的)exercism.io 进行练习。该练习涉及创建一个Robot能够存储名称的数据类型,该名称是随机生成的(练习Readme包含在下面)。

对于那些不熟悉它的人来说,exercism.io学习模型是基于学生生成代码的自动测试。每个练习都包含一系列测试(由测试作者编写),并且解决方案代码必须能够通过所有测试。我们的代码必须通过给定练习的测试文件中的所有测试,然后才能进入下一个练习——一个有效的模型,imo。(Robot Name是练习#20左右。)

在这个特定的练习中,我们被要求创建一个Robot数据类型和三个附带的函数mkRobotrobotNameresetName

  • mkRobot生成一个实例Robot
  • robotName生成并“返回”未命名的唯一名称Robot(即,robotName不覆盖预先存在的名称);如果 aRobot已经有名称,它只是“返回”现有名称
  • resetName用一个新名称覆盖预先存在的名称。

在这个特定的练习中,有 7 个测试。测试检查:

  • 0)robotName生成符合指定模式的名称(名称长度为 5 个字符,由两个字母后跟三个数字组成,例如 AB123、XQ915 等)
  • 1) 分配的名称robotName是持久的(即,假设我们创建机器人 A 并使用 为他(或她)分配一个名称robotName;第二次调用robotName(在机器人 A 上)不应覆盖他的名称)
  • 2)robotName为不同的机器人生成唯一的名称(即,它测试我们实际上是在随机化过程)
  • 3)resetName生成符合指定模式的名称(类似于测试#0)
  • 4) 分配的名称resetName是持久的
  • 5)resetName分配不同的名称(即,resetName给机器人一个与其当前名称不同的名称)
  • 6)resetName一次只影响一个机器人(即,假设我们有机器人 A 和机器人 B;重置机器人 A 的名称不应影响机器人 B 的名称)并且 (ii) 生成的名称resetName是持久的

作为参考,这里是测试本身:https ://github.com/dchaudh/exercism-haskell-solutions/blob/master/robot-name/robot-name_test.hs


我被困在哪里:

版本 1(原始帖子): 目前,我的代码在三个测试(#1、#4 和 #6)中失败,所有这些测试都与机器人名称的持久性有关。.

版本 2:(临时) 现在我的代码仅在一个测试(#5)中失败 - 测试 5 与更改我们已经创建的机器人的名称有关 (感谢 bheklikr 的有用评论帮助我清理版本 1)

版本 3(最终版):由于 Cirdec 在下面的详尽帖子,代码现已修复(并通过了所有测试)。为了将来读者的利益,我将代码的最终版本与两个早期版本一起包括在内(以便它们可以跟随各种评论/答案)。


第 3 版(最终版): 这是基于 Cirdec 以下回答的最终版(我强烈建议您阅读)。事实证明,我最初的问题(询问如何使用 System.Random 创建持久变量)是完全错误的,因为我最初的实现是不健全的。相反,我的问题应该是询问如何在 IO monad 中使用可变结构(Cirdec 在下面解释)。


版本 2(临时): 基于 bheklikr 的评论,该评论清理了该mkRobotName功能并帮助开始修复 mkRobot 功能。此版本的代码仅在测试 #5 中产生错误 - 测试 #5 与更改机器人的名称有关,这激发了对可变结构的需求......


版本 1(原始):回想起来,这可笑的糟糕。此版本在测试#1、#4 和#6 中失败,所有这些测试都与机器人名称的持久性有关。

0 投票
2 回答
93 浏览

haskell - Haskell 在一个意想不到的函数上使用 IO

问题:

如何为需要“SDL.Surface”的函数提供“IO SDL.Surface”?

我宁愿重新考虑我的整个方法,也不愿诉诸使用“unsafePerformIO”之类的东西,除非这实际上是使用它的正确时间(我对此表示怀疑)。

更多信息:

我有一个填充了数字和文件路径的文件,我已经解析了这个文件并将位于这些路径的图像加载到列表 [(Int, IO SDL.Surface)] 中。问题是,SDL.blitSurface函数需要一个正常的 SDL.Surface。

错误信息:

我不确定是否需要源代码来回答这个问题,但我还是会提供一些以防万一:

要加载我使用的图像文件:

要创建我使用的数字和图像列表:

为了从这个列表中检索正确的图片,我使用了这个函数:

最后我使用带有 SDL.blitSurface 的 imageFromID 来绘制图像,但由于 IO 的原因我不能。

0 投票
4 回答
276 浏览

haskell - 在 `IO` 代码中使用 `Maybe` 值的大小写重构“楼梯”

以下函数f尝试Int通过使用IO (Maybe Int)函数两次读取 an ,但在成功读取 one 后“短路”执行Int

有没有重构这段代码的好方法?如果我将其扩展到 3 次尝试,这将变得非常棘手……</p>

(我的思考过程:看到这个“楼梯”告诉我也许我应该使用 的Monad实例Maybe,但是由于这已经在IOmonad 中,所以我必须使用MaybeT(?)。但是,我只需要一个readIntto成功,所以Maybe单子第一次Nothing出错的行为在这里是错误的......)

0 投票
4 回答
456 浏览

haskell - 猜我的号码,一元性头痛

为了测试我在 Haskell 中的技能,我决定实现你在Land of Lisp / Realm of Racket中找到的第一款游戏。“猜我的号码”游戏。游戏依赖于可变状态来运行,因为它必须不断更新程序的上限和下限,以了解用户正在考虑的值。

它有点像这样:

现在,这种事情(据我所知)在 Haskell 中并不完全可能,从 REPL 中调用一些修改全局可变状态的函数,然后立即打印结果,因为它违反了不变性原则。因此,所有的交互都必须存在于一个IO和/或State单子中。这就是我卡住的地方。

我似乎无法将IOmonad 和Statemonad 结合起来,所以我可以在同一个函数中获取输入、打印结果和修改状态。

这是我到目前为止得到的:

我现在需要做的就是想办法

  • 打印初始猜测
  • 接收想要更小/更大数字的命令
  • 相应地修改状态
  • 递归调用函数,让它再次猜测

我如何结合IOState以优雅的方式实现这一目标?

注意:我知道这可能完全不用状态就可以实现;但我想让它保持原汁原味

0 投票
3 回答
81 浏览

haskell - 是否可以在不使用自定义类型的情况下模拟 StateT 的行为?

如果我们有以下两个函数,加法和减法,很容易将它们链接起来以对输入运行一系列计算:

如果我们想在每次计算完成后打印出状态,我们使用StateTmonad 转换器:

StateT是否可以在没有或任何自定义数据类型的情况下复制这种“组合计算和打印” ?

据我所知,MaybeT IO a可以使用 using 执行所有可以执行的过程IO (Maybe a),但这似乎是因为它只是嵌套的 monad。另一方面,StateT可能没有替代方案,因为s -> (a,s)s -> m (a,s)

我只能看到代码的两个方向:使用State Int (IO ())or IO (State Int ()),但考虑到实现StateT

我相信这是不可能的。我对么?

注意:我知道这完全不切实际,但是经过几个小时的工作后我找不到任何解决方案,这意味着我是正确的,或者我的技能不足以完成这项任务。

0 投票
1 回答
218 浏览

scala - Scalaz 中的 Tower[A] 和 IvoryTower 是什么?

当我查看scalaz.effect.IO源代码时,我注意到它有一个apply具有以下签名的方法:

Tower[A]IvoryTower定义为:

有一个实例Tower

这些课程的目的是什么?为什么IO.apply接受 type 的参数Tower[IvoryTower]

0 投票
2 回答
456 浏览

haskell - 如何在另一个 Monad 中使用 IO Monad

我使用 MongoDB 库来处理来自 Mongodb 的数据。有一个称为Action表示 DB 读取或写入操作的 Monad https://github.com/TonyGen/mongoDB-haskell/blob/master/doc/tutorial.md。但是,我发现当我在 monad Action 中时,我也想做一些必须在 IO Monad 中的 IO。一些代码如

liftIO在任何单子之前都有一个IO,我认为它可能很冗长。有什么简洁的方法来处理这个吗?