问题标签 [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.
haskell - haskell 程序的灵活参数数量
我正在使用System.FilePath.Find
filemanip 模块递归地查找我需要处理的所有文件(这里我将仅使用打印到控制台作为要执行的操作,以免混淆事物)。现在,这段代码:
与此通话效果很好
./myprog tet .
在这种情况下,get
参数将被忽略(稍后将是输出数据库文件),并递归搜索第二个参数以查找匹配文件。它还允许我指定一个文件,这非常完美!
但是,我希望能够指定
./myprog tet path1 path2 path4 file1
但这当然在模式匹配中失败了:
./myprog tet . .
myprogt:用户错误(myprog.hs:11:9-22 处的 do 表达式中的模式匹配失败)
现在,我如何使这个程序更灵活,以便我可以接受两个以上的参数?
很抱歉问这个问题,但我的 Haskell 知识是有限的,但我在第一个项目中必须做的每件新事情都会增加。
haskell - 在 haskell 程序中使用返回的 EitherT
我正在尝试在我正在处理的 Haskell 项目中使用“引文解析”包,但在实际代码中使用 EitherT 时遇到了麻烦。我知道它们是单子变换器,我想我理解这意味着什么,但是我似乎无法真正弄清楚如何使用它们。代表我正在尝试做的玩具示例如下:
在这里,resolveEither
有类型:
并runEitherT $ resolveEither "ref"
具有以下类型:
但是,这会产生以下错误:
我不知道如何解决或解决。
任何帮助将不胜感激,特别是从使用角度而不是实现角度处理 monad 转换器的教程的指针。
编辑:
为了反映 dfeuer 和 Christian 对答案的评论,如果我将 main 更改为以下内容,我仍然会遇到错误:
我现在得到的错误是:
我正在编辑我的问题以及发表评论,因为这里的代码格式比在评论中要容易得多。
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 允许我们使用>>=
这两个函数呢?
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
数据类型和三个附带的函数mkRobot
:robotName
和resetName
。
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 中失败,所有这些测试都与机器人名称的持久性有关。
haskell - Haskell 在一个意想不到的函数上使用 IO
问题:
如何为需要“SDL.Surface”的函数提供“IO SDL.Surface”?
我宁愿重新考虑我的整个方法,也不愿诉诸使用“unsafePerformIO”之类的东西,除非这实际上是使用它的正确时间(我对此表示怀疑)。
更多信息:
我有一个填充了数字和文件路径的文件,我已经解析了这个文件并将位于这些路径的图像加载到列表 [(Int, IO SDL.Surface)] 中。问题是,SDL.blitSurface函数需要一个正常的 SDL.Surface。
错误信息:
我不确定是否需要源代码来回答这个问题,但我还是会提供一些以防万一:
要加载我使用的图像文件:
要创建我使用的数字和图像列表:
为了从这个列表中检索正确的图片,我使用了这个函数:
最后我使用带有 SDL.blitSurface 的 imageFromID 来绘制图像,但由于 IO 的原因我不能。
haskell - 在 `IO` 代码中使用 `Maybe` 值的大小写重构“楼梯”
以下函数f
尝试Int
通过使用IO (Maybe Int)
函数两次读取 an ,但在成功读取 one 后“短路”执行Int
:
有没有重构这段代码的好方法?如果我将其扩展到 3 次尝试,这将变得非常棘手……</p>
(我的思考过程:看到这个“楼梯”告诉我也许我应该使用 的Monad
实例Maybe
,但是由于这已经在IO
monad 中,所以我必须使用MaybeT
(?)。但是,我只需要一个readInt
to成功,所以Maybe
单子第一次Nothing
出错的行为在这里是错误的......)
haskell - 猜我的号码,一元性头痛
为了测试我在 Haskell 中的技能,我决定实现你在Land of Lisp / Realm of Racket中找到的第一款游戏。“猜我的号码”游戏。游戏依赖于可变状态来运行,因为它必须不断更新程序的上限和下限,以了解用户正在考虑的值。
它有点像这样:
现在,这种事情(据我所知)在 Haskell 中并不完全可能,从 REPL 中调用一些修改全局可变状态的函数,然后立即打印结果,因为它违反了不变性原则。因此,所有的交互都必须存在于一个IO
和/或State
单子中。这就是我卡住的地方。
我似乎无法将IO
monad 和State
monad 结合起来,所以我可以在同一个函数中获取输入、打印结果和修改状态。
这是我到目前为止得到的:
我现在需要做的就是想办法
- 打印初始猜测
- 接收想要更小/更大数字的命令
- 相应地修改状态
- 递归调用函数,让它再次猜测
我如何结合IO
并State
以优雅的方式实现这一目标?
注意:我知道这可能完全不用状态就可以实现;但我想让它保持原汁原味
haskell - 是否可以在不使用自定义类型的情况下模拟 StateT 的行为?
如果我们有以下两个函数,加法和减法,很容易将它们链接起来以对输入运行一系列计算:
如果我们想在每次计算完成后打印出状态,我们使用StateT
monad 转换器:
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
我相信这是不可能的。我对么?
注意:我知道这完全不切实际,但是经过几个小时的工作后我找不到任何解决方案,这意味着我是正确的,或者我的技能不足以完成这项任务。
scala - Scalaz 中的 Tower[A] 和 IvoryTower 是什么?
当我查看scalaz.effect.IO
源代码时,我注意到它有一个apply
具有以下签名的方法:
Tower[A]
并IvoryTower
定义为:
有一个实例Tower
:
这些课程的目的是什么?为什么IO.apply
接受 type 的参数Tower[IvoryTower]
?
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
,我认为它可能很冗长。有什么简洁的方法来处理这个吗?