mapM 的惰性版本

2024-03-09

假设我在使用 IO 时收到了大量的项目列表:

as <- getLargeList

现在我正在尝试申请fn :: a -> IO b onto as:

as <- getLargeList
bs <- mapM fn as

mapM有类型mapM :: Monad m => (a -> m b) -> [a] -> m [b],这就是我在类型匹配方面所需要的。但它会在内存中构建所有链,直到返回结果。我正在寻找类似物mapM,它将惰性地工作,这样我就可以使用 head ofbs而尾巴仍在建造中。


不使用unsafeInterleaveIO或任何与此相关的惰性 IO。这正是创建 iteratee 来解决的问题:避免惰性 IO,这会带来不可预测的资源管理。诀窍是从不建立清单并不断使用 iteratees 对其进行流式传输,直到使用完毕。我将使用我自己的图书馆中的示例,pipes,来证明这一点。

首先,定义:

import Control.Monad
import Control.Monad.Trans
import Control.Pipe

-- Demand only 'n' elements
take' :: (Monad m) => Int -> Pipe a a m ()
take' n = replicateM_ n $ do
    a <- await
    yield a

-- Print all incoming elements
printer :: (Show a) => Consumer a IO r
printer = forever $ do
    a <- await
    lift $ print a

现在,让我们对我们的用户客气一点,要求他们为我们生成非常大的列表:

prompt100 :: Producer Int IO ()
prompt100 = replicateM_ 1000 $ do
    lift $ putStrLn "Enter an integer: "
    n <- lift readLn
    yield n

现在,让我们运行它:

>>> runPipe $ printer <+< take' 1 <+< prompt100
Enter an integer:
3<Enter>
3

它只提示用户输入一个整数,因为我们只需要一个整数!

如果你想更换prompt100输出来自getLargeList,你只需写:

yourProducer :: Producer b IO ()
yourProducer = do
    xs <- lift getLargeList
    mapM_ yield xs

...然后运行:

>>> runPipe $ printer <+< take' 1 <+< yourProducer

这将延迟流式传输列表,并且永远不会在内存中构建列表,所有这些都无需使用不安全IO黑客。要更改您需要的元素数量,只需更改您传递给的值take'

有关更多此类示例,请阅读pipes教程 http://hackage.haskell.org/packages/archive/pipes/2.3.0/doc/html/Control-Pipe-Tutorial.html at Control.Pipe.Tutorial.

要了解有关惰性 IO 为何会导致问题的更多信息,请阅读 Oleg 关于该主题的原始幻灯片,您可以找到该幻灯片here http://okmij.org/ftp/Haskell/Iteratee/IterateeIO-talk-notes.pdf。他很好地解释了使用惰性 IO 的问题。任何时候你觉得有必要使用惰性 IO 时,你真正想要的是一个 iteratee 库。

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

mapM 的惰性版本 的相关文章

  • 用于遇到 [...] 的 Haskell Parsec 解析器

    我正在尝试使用 Parsec 在 Haskell 中编写一个解析器 目前我有一个可以解析的程序 test x 1 2 3 end 执行此操作的代码如下 testParser do reserved test v lt identifier
  • QuickCheck是否可以生成任意函数

    我试图为身份编写一个 QuickCheck 测试 f y f y 我最初的计划是编写一个返回函数和整数的任意生成器 具有签名Gen Int gt Int Int 并在prop DollerDoesNothing使用 不使用测试该功能应用程序
  • 如何在haskell中获取变量名称

    我来到 haskell 时有一些 c 背景知识 想知道是否有类似的 define print a printf s d n a a int a 5 print a 应该打印 a 5 这是 augustss 提到的 TH 解决方案 LANGU
  • 在 monad 转换器类型类中使用列表 monad?

    我的目标是创建一个在 ReaderT WriterT 堆栈或 RWS 堆栈中使用列表 monad 的函数 更一般地说 如何在 mtl 类型类 例如 MonadReader MonadWriter 中使用列表 monad 我为什么要尝试这样做
  • ST monad 是如何工作的?

    我知道 ST monad 有点像 IO 的弟弟 而 IO 又是添加了状态 monadRealWorld魔法 我可以想象状态 也可以想象 RealWorld 以某种方式放入 IO 中 但每次我写一个类型签名ST the sST monad 的
  • 如何打乱列表?

    如何从一组数字 1 2 3 直到我击中x 我的计划是重新调整列表 1 2 3 并把它砍在x chopAt 3 2 3 1 2 3 chopAt 3 2 1 3 2 1 3 chopAt 3 3 1 2 3 chopAt chopAt x y
  • 我是否需要采取明确的操作来促进与持久数据结构的共享?

    我来自命令式背景 正在尝试实现一个简单的不相交集 并集查找 数据结构 以获得在 Haskell 中创建和修改 持久 数据结构的一些练习 目标是有一个简单的实现 但我也关心效率 我的问题与此相关 首先 我创建了一个按等级并集的不相交集森林实现
  • Haskell 项目可以使用 cmake 吗?

    我正在计划一个用 Haskell 编写的项目 也许也有一些部分是用 C 编写的 对于构建系统 我决定不选择 Haskell 程序 cabal 的常见选择 主要是因为我想了解其他语言的构建程序是如何工作的 我听说过 CMake 我认为这是一个
  • 在 Ruby 控制台应用程序中获取键盘事件(无需按“Enter”输入)的最佳方法是什么?

    我在互联网上寻找这个答案已经有一段时间了 发现其他人也在问同样的事情 即使在这里也是如此 因此 这篇文章将介绍我的案例以及对我找到的 解决方案 的回应 我对 Ruby 很陌生 但出于学习目的 我决定创建一个 gem here https g
  • 如何使用foldr为列表创建显示实例?

    我想为我的数据类型 我的列表 编写自己的显示实例 到目前为止 我的方法是有效的 但我总是在末尾有一个逗号 我已经尝试用最后一个元素启动折叠并将其从列表中删除 但它很麻烦而且不起作用 有没有更简单的方法来获得正确的解决方案 实际 1 2 3
  • 替换文件中的字符串

    我正在寻找一种方法来替换文件中的字符串而不将整个文件读入内存 通常我会使用 Reader 和 Writer 即如下所示 public static void replace String oldstring String newstring
  • Haskell 中的所有内容都存储在 thunk 中吗,甚至是简单的值?

    以下值 表达式 函数的 thunk 在 Haskell 堆中是什么样子的 val 5 is val a pointer to a box containing 5 add x y x y result add 2 val main prin
  • 我可以从 GHCi 中找到 GHC 版本吗?

    gt 我在里面输入什么GHCi发现它正在使用哪个 GHC 版本 gt import System Info gt browse arch String compilerName String compilerVersion Data Ver
  • 使用 Haskell 绘制图表

    是否可以使用 Haskell 绘制一个简单的图表 你们中的任何人都可以告诉我该怎么做吗 该图应至少包含 3 个点 Haskell 图表 https github com timbod7 haskell chart似乎不错 The wiki
  • 由于垃圾收集,Haskell 程序中会出现多长时间的暂停?

    关于我的另一个问题Haskell 集合可以保证每个操作的最坏情况范围 https stackoverflow com q 12393104 1333025 我很好奇 垃圾收集会导致多长时间的暂停 Haskell 是否使用某种增量垃圾收集 以
  • Haskell / cabal 包的解决方法受到 Nix 和 Cabal 的限制?

    我最近开始开发反射平台 https github com reflex frp reflex platform 有一些额外的配置类似于优秀的反射项目骨架 https github com ElvishJerricco reflex proj
  • 这是 unsafeCoerce 的安全使用吗?

    我遇到的情况是 我目前正在使用极其可怕的函数 unsafeCoerce 幸运的是 这并不是为了任何重要的事情 但我想知道这是否是该函数的安全使用 或者是否有其他方法可以解决其他人知道的这个特定问题 我的代码类似于以下内容 data Toke
  • 如何让 esqueleto 为我生成 SQL 字符串?

    我怎样才能让esqueleto从a生成一个SQL字符串from陈述 的文档toRawSql说 你可以打开持久的查询日志记录 我尝试了所有可能的形式MonadLogger我可以理解 但它从未打印任何 SQL 同一文档还说 手动使用此功能 是可
  • 检索 Haskell 项目中所有导入的列表

    因此 我的最终目标是通过确保项目导入的所有实体都存在于其声称可以使用的版本中 来评估 cabal 文件中依赖项的准确性 一个好的开始是找到单个源文件使用的所有导入实体的列表 可选地包含有关它们来自何处的信息 我愿意暂时忽略类实例的情况 因为
  • 优化 Haskell 内循环

    仍在 Haskell 中进行 SHA1 实现 我现在已经有了一个有效的实现 这是内部循环 iterateBlock Int gt Word32 gt Word32 gt Word32 gt Word32 gt Word32 gt Word3

随机推荐

  • Excel:如果单元格 1 包含 X、Y 或 Z,则单元格 2 应等于 W

    从标题来看 我需要 Excel 根据相应的 A 行单元格内容自动填充 B 行单元格 所以如果细胞A1包含 X 或 Y 或 Z 则单元格B1应等于 W 或者如果A1包含 G 或 H 或 J 细胞B1应等于 W 您可以尝试将以下公式添加到 B1
  • PHP Laravel:无法建立连接,因为目标机器主动拒绝它

    我正在 Laravel 5 中构建一个 Web 应用程序 该应用程序应该获取存储在 MySQL 数据库中的 类别名称 并显示一个表单以添加新的 类别名称 当我执行命令时php artisan serve我导航到http localhost
  • 位置:子元素上的粘性行为,而父元素不粘性?

    我正在努力实现一些我不确定是否可能实现的目标 请注意 我正在寻找仅 CSS 的解决方案 我知道我可以用 JS 解决这个问题 但我不想这样做 考虑下面的笔 https codepen io fchristant pen PjoKOq http
  • 使用 Alter 命令的 Oracle 存储过程

    我正在尝试构建一个 Oracle 存储过程 它将接受表名作为参数 然后该过程将重建表上的所有索引 我的问题是在存储过程中使用 ALTER 命令时出现错误 就好像 PLSQL 不允许该命令一样 Use the execute immediat
  • 如何使用 Ant、文件和文件夹“chmod -R +w”?

    我想做相当于chmod R w foo in an Ant构建脚本 到目前为止我正在使用这个
  • 如何解决 Tridion 弹出页面中的“Tridion 未定义”错误?

    我正在自定义功能区工具栏并向其添加一个按钮 每当我单击该按钮时 它都会打开一个 aspx 页面 允许作者选择一些数据 这些数据将附加到现有的 RTF 字段内容中 但是当打开弹出窗口时 浏览器 Internet Explorer 中出现以下错
  • 使用队列进行基数排序

    我想创建一个基数排序 http en wikipedia org wiki Radix sort使用队列实现 我无法弄清楚我的代码的哪一部分有问题或者我应该阅读哪些资源 我的代码可能完全错误 但这是我的实现 没有任何帮助 我还没有参加数据结
  • 不带重定向的不记名令牌 WEB API asp.net core

    我是 ASP NET Core 的新手 我正在尝试使用来自 Google Facebook 的 jwt 身份验证和 OpenOauth 制作一个小型 Web 服务 我读过这篇文章 https stormpath com blog token
  • System.Windows.Threading.DispatcherTimer 在哪里?

    快到长周末了 我正在尝试创建一个 DispatcherTimer 我找到了一些示例代码 但由于缺少命名空间而无法运行它 我有命名空间 System Windows Threading 但我可以在哪个程序集中找到它 我尝试了 System S
  • Pandas GroupBy 中的计数和连接整数

    假设这是我的 df A B C 0 a 33 13 1 b 44 14 2 a 55 15 3 a 66 16 4 b 77 17 5 c 88 18 我尝试得到这样的东西 A B B C count list sum 0 a 3 33 5
  • 如果类列表包含多个特定类

    我需要一个函数来触发元素recordplayerstick包含pinplace or pinsongplay班级 我当前的代码返回语法错误 这样做的正确方法是什么 if document getElementById recordplaye
  • LINQ to DataTable 简单快速

    我是 LINQ 新手 我想将 LINQ 查询转换为 DataTable DataClassesDataContext db new DataClassesDataContext MyConncectionString IEnumerable
  • INVoiceShortcutCenter.shared.getAllVoiceShortcuts 在 iOS 13 中不会返回任何内容

    我不确定我做错了什么 但在这个方法中 INVoiceShortcutCenter shared getAllVoiceShortcuts vShortCuts error in print vShortCuts vShortCuts 是一个
  • 填充形状的图像不会在 FabricJS 中使用 loadFromJSON 加载

    I have JSON带有 Fabric Rect 对象的数据 当我尝试加载这个时JSON数据到织物画布上从JSON加载 形状加载完美 但形状中填充的图案未渲染 仅在单击形状后才会渲染图案 我已将我的代码复制到织物厨房水槽执行模块中 并尝试
  • 无法使用 Apache POI 读取 Excel

    我正在使用 Apache POI 读取 excel 但它不断给出 XSSFWorkbook 类定义发现错误的错误 我使用了不同版本的 Apache poi jar 库 即 4 1 4 0 和 3 12 但它们似乎都没有修复此错误 这是当前导
  • 从 Graphite 迁移到图形浏览器

    石墨网络应用程序不鼓励临时绘图 Graphiti 等人只是花哨的 UI 虽然改进了 UI UX 但对于困扰 Graphite Webapp 的固有线性度量搜索没有做太多事情 如果这里错了请纠正我 但是only我遇到的鼓励临时绘图的选项是图形
  • 请求:网络应用程序的最小框架

    我即将构建一个框架 将 xml 带有嵌入代码 解析为具有 ajax 功能的自动生成的 Web 应用程序 现在 我不想重新发明轮子 所以感谢任何现有的可用解决方案 归结为 有可用的框架吗 这为我创建了回调代码等 最好是php If not 适
  • 如何在 MVC4 中使用 type="url" 而无需 jQuery 将字段验证为 URL?

    情况是这样的 我这里有一个很大的 URL 文本输入框 https asafaweb com https asafaweb com 不过 这不需要遵守 URL 的严格定义 我允许没有方案的地址 然后出于可用性目的默认为 HTTP 例如 sta
  • 如何在iOS中制作一个水平可滚动的UITabBar?

    我的应用程序中的 UITabBar 由 10 多个项目组成 但宽度足以放置所有 10 多个项目 如何在 iOS 中制作水平可滚动的 UITabBar Thanks 至少在某种程度上 你必须自己动手 What might工作 将创建一个 UI
  • mapM 的惰性版本

    假设我在使用 IO 时收到了大量的项目列表 as lt getLargeList 现在我正在尝试申请fn a gt IO b onto as as lt getLargeList bs lt mapM fn as mapM有类型mapM M