访问函数中的环境

2024-05-09

In main我可以读取我的配置文件,并将其提供为runReader (somefunc) myEnv正好。但somefunc不需要访问myEnv读者提供,链中的下一对也没有提供。需要 myEnv 中某些内容的函数是一个微小的叶函数。

如何在不将所有干预函数标记为的情况下访问函数中的环境(Reader Env)?这是不对的,因为否则你一开始就会传递 myEnv 。通过多个级别的函数传递未使用的参数是很丑陋的(不是吗?)。

我可以在网上找到很多示例,但它们似乎在 runReader 和访问环境之间只有一层。


我接受克里斯·泰勒的,因为它是最彻底的,而且我可以看到它对其他人有用。还要感谢 Heatsink,他是唯一一个尝试直接回答我的问题的人。

对于有问题的测试应用程序,我可能会完全放弃 Reader 并传递环境。它不会给我买任何东西。

我必须说,我仍然对向函数 h 提供静态数据不仅改变其类型签名,而且改变调用它的 g 和调用 g 的 f 的类型签名的想法感到困惑。尽管涉及的实际类型和计​​算没有改变,但所有这些都是如此。看起来实现细节在代码中到处泄露,但没有带来任何实际好处。


You do给所有东西返回类型Reader Env a,尽管这并不像你想象的那么糟糕。一切都需要这个标签的原因是如果f取决于环境:

type Env = Int

f :: Int -> Reader Int Int
f x = do
  env <- ask
  return (x + env)

and g calls f:

g x = do
  y <- f x
  return (x + y)

then g还取决于环境 - 行中绑定的值y <- f x可能会有所不同,具体取决于传入的环境,因此适当的类型g is

g :: Int -> Reader Int Int

这其实是一件好事!类型系统迫使您明确识别函数依赖于全局环境的位置。您可以通过定义短语的快捷方式来减轻打字的痛苦Reader Int:

type Global = Reader Int

现在你的类型注释是:

f, g :: Int -> Global Int

这更具可读性。


另一种方法是将环境显式传递给所有函数:

f :: Env -> Int -> Int
f env x = x + env

g :: Env -> Int -> Int
g x = x + (f env x)

这是可行的,事实上,从语法角度来看,它并不比使用Reader单子。当你想要扩展语义时,困难就来了。假设您还依赖于类型的可更新状态Int其中计算函数应用程序。现在您必须将您的功能更改为:

type Counter = Int

f :: Env -> Counter -> Int -> (Int, Counter)
f env counter x = (x + env, counter + 1)

g :: Env -> Counter -> Int -> (Int, Counter)
g env counter x = let (y, newcounter) = f env counter x
                  in (x + y, newcounter + 1)

这显然不太令人愉快。另一方面,如果我们采用单子方法,我们只需重新定义

type Global = ReaderT Env (State Counter)

的旧定义f and g继续工作,没有任何麻烦。要更新它们以具有应用程序计数语义,我们只需将它们更改为

f :: Int -> Global Int
f x = do
  modify (+1)
  env <- ask
  return (x + env)

g :: Int -> Global Int
g x = do
  modify(+1)
  y <- f x
  return (x + y)

现在它们工作得很好。比较两种方法:

  • 当我们想要向程序添加新功能时,显式传递环境和状态需要完全重写。

  • 使用单子接口需要更改三行 - 即使我们更改了第一行,程序仍然可以继续工作,这意味着我们可以增量地进行重构(并在每次更改后进行测试),这降低了重构引入的可能性新的错误。

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

访问函数中的环境 的相关文章

随机推荐

  • 文本末尾的空格在右对齐 UITextField 中不可见

    我有一个右对齐的UITextField 最初编辑时 文本末尾不会出现空格 我用这个解决了this https stackoverflow com q 19569688 1971013 替换 与不间断的 u00a0 然而 上面仅在编辑文本字段
  • 在初始化程序中重新加载命名空间常量

    今天遇到一个有趣的情况 我不确定如何解决 给定一个带有初始化器的 Rails 应用程序 file config initializers integrations rb Integrations CONFIGS key gt value f
  • Intel 64 和 IA-32 上的 MESI 有何意义

    MESI 的要点是保留共享内存系统的概念 然而 对于存储缓冲区 事情就变得复杂了 一旦数据到达 MESI 实现的缓存 下游内存就会保持一致 然而 在此之前 每个核心可能对内存位置 X 中的内容存在分歧 具体取决于每个核心的本地存储缓冲区中的
  • 如何使用 JDA 在 Discord 服务器(不是用户/机器人 DM)中创建私有频道:Java Discord API

    我试图让机器人在公会中创建一个私人频道 但在 JDA 文档中找不到任何允许这种情况发生的内容 调用时返回的 ChannelActioncreateTextChannel 在返回中明确将文本作为通道类型 return new ChannelA
  • 如何获取列中每个不同值的计数? [复制]

    这个问题在这里已经有答案了 我有一个名为 posts 的 SQL 表 如下所示 id category 1 3 2 1 3 4 4 2 5 1 6 1 7 2 每个类别编号对应一个类别 我将如何计算每个类别出现在帖子中的次数一条 SQL 查
  • 除法的时间复杂度是多少?

    我使用除法算法 根据https en wikipedia org wiki Computational complexity of mathematical operations https en wikipedia org wiki Co
  • iPython 笔记本上的内联数学模式

    在 iPython 笔记本中 我如何编写数学公式 例如r 2在一行中 乳胶词汇中的内联数学模式 IE 打印公式的时候可以不换行吗 如果像在 LaTeX 中一样 它应该是 r 2 但它不起作用 感谢您的帮助 在 Markdown 单元格中 您
  • 如何编辑 Mailchimp 自动化电子邮件的纯文本版本?

    我已经使用 Mailchimp 运行自动化工作流程一段时间了 其中有一个简单的欢迎新闻通讯 自动化电子邮件编辑器仅允许我编辑电子邮件的 HTML 版本 并自动生成基于文本的版本 但是 它仅在首次创建电子邮件时生成纯文本版本 从那时起 我已经
  • JKS、BKS 和 PKCS12 文件格式

    我正在设置一个无头服务器 该服务器使用用户提供的数据 JS CSS HTML 密钥库 为 Android 构建 Phonegap 混合应用程序 我想进行一些基本的客户端检查 以确保上传的密钥库有效 对于 JKS 文件 我发现可以通过确保提供
  • Excel 2013 COM API 在服务帐户下挂起 ExportAsFixedFormat

    我有一个 NET Windows 服务 它调用 Excel 2013 COM API 以在 PDF 上导出 Excel 文档 我已尝试使用在两个不同域帐户下运行的 Windows 服务来执行此代码 这两个帐户都是运行代码的计算机上的本地管理
  • Matplotlib:imshow 中 set_data 对绘图没有影响

    我有一个奇怪的错误 没有你的帮助我无法修复 当我设置图像后imshow在 matplotlib 中 即使我用方法更改它 它也始终保持不变set data 看看这个例子 import numpy as np from matplotlib i
  • GUI设计技术增强用户体验[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 将文本置于圆形按钮上居中

    我想创建一个按钮圆形链接 其中包含文本 但我在将文本置于圆形按钮内居中时遇到问题 行高太大 对这个问题有什么建议吗 这是代码 https jsfiddle net hma443rL https jsfiddle net hma443rL b
  • 如何在 PowerShell 中使用参数执行外部程序?

    我读过这个答案堆栈溢出 https stackoverflow com questions 1673967 how to run exe in powershell with parameters with spaces and quote
  • 更改svg中半圆的背景颜色

    我想在此 svg 代码上创建上弦月和第三弦月
  • Azure 工作簿中的可选下拉参数

    我想在 Azure 工作簿中创建可选下拉参数 创建下拉参数有了本指南 https 20https learn microsoft com en us azure azure monitor visualize workbooks dropd
  • 提交 ID 从哪里来?

    我只是对此很好奇 提交 ID 不能是随机的 因为它们需要是唯一的 不过 它们似乎是随机的 这让我想知道 为什么它们不只是连续的数字 我的意思是 它们只需要在存储库中是唯一的 对吧 或者我在这里错了 Thanks Git 提交 ID 是 SH
  • 我在哪里可以学习如何使 C++ 程序与操作系统 (Linux) 交互

    我是一个 C 初学者 我想创建与操作系统交互的小程序 使用 Kubuntu Linux 到目前为止 我还没有找到任何教程或手册来让 C 与操作系统交互 在 PHP 中 我可以使用命令 exec 或反引号运算符来启动通常在控制台中执行的命令
  • xml2 包 (R) 中的 xml_find_all 函数未找到相关节点

    我使用 R 中的 xml2 包来访问 xml 数据 发现它在不同的 xml documents 上表现不同 在这个宠物的例子中 library xml2 doc lt read xml
  • 访问函数中的环境

    In main我可以读取我的配置文件 并将其提供为runReader somefunc myEnv正好 但somefunc不需要访问myEnv读者提供 链中的下一对也没有提供 需要 myEnv 中某些内容的函数是一个微小的叶函数 如何在不将