在 Haskell 中提升高阶函数

2023-11-29

我正在尝试构造一个类型的函数:

liftSumthing :: ((a -> m b) -> m b) -> (a -> t m b) -> t m b

where t是一个 Monad 转换器。具体来说,我有兴趣这样做:

liftSumthingIO :: MonadIO m => ((a -> IO b) -> IO b) -> (a -> m b) -> m b

我摆弄了一些 Haskell 魔法库,但没有成功。我怎样才能得到它 对吧,或者也许有一个我没有找到的现成解决方案?


这不能普遍地完成MonadIO实例是因为IO键入负数位置。 hackage 上有一些库可以针对特定实例执行此操作(单子控制, 单子皮),但是关于它们在语义上是否合理存在一些争论,特别是关于它们如何处理异常和类似的奇怪问题IO你的事情。

编辑:有些人似乎对积极/消极立场的区别感兴趣。实际上,没什么可说的(您可能已经听过它,但名称不同)。该术语来自子类型领域。

子类型化背后的直觉是“a是一个子类型b(我会写a <= b)当a可以在任何地方使用b相反,“是预期的”。在很多情况下,决定子类型很简单;对于产品,(a1, a2) <= (b1, b2)每当a1 <= b1 and a2 <= b2例如,这是一个非常简单的规则。但也有一些棘手的情况;例如,我们什么时候应该决定a1 -> a2 <= b1 -> b2?

好吧,我们有一个函数f :: a1 -> a2和一个期望类型函数的上下文b1 -> b2。所以上下文将使用f的返回值就好像它是b2,因此我们必须要求a2 <= b2。棘手的是上下文将提供f with a b1, 虽然f将像使用它一样使用它a1。因此,我们必须要求b1 <= a1——这与你可能猜到的相反!我们这么说a2 and b2是“协变的”,或者出现在“正位置”,并且a1 and b1是“逆变的”,或者出现在“负位置”。

(顺便说一句:为什么是“正”和“负”?它是由乘法驱动的。考虑这两种类型:

f1 :: ((a1 -> b1) -> c1) -> (d1 -> e1)
f2 :: ((a2 -> b2) -> c2) -> (d2 -> e2)

什么时候应该f1的类型是 的子类型f2的类型?我陈述这些事实(练习:使用上面的规则检查这一点):

  • 我们本应该e1 <= e2.
  • 我们本应该d2 <= d1.
  • 我们本应该c2 <= c1.
  • 我们本应该b1 <= b2.
  • 我们本应该a2 <= a1.

e1处于积极的位置d1 -> e1,这又在类型中处于正位置f1;而且,e1在该类型中处于积极位置f1总体而言(因为根据上述事实,它是协变的)。它在整个项中的位置是其在每个子项中的位置的乘积:正 * 正 = 正。相似地,d1处于消极位置d1 -> e1,在整个类型中处于积极的位置。负数 * 正数 = 负数,并且d变量确实是逆变的。b1在类型中处于正位置a1 -> b1,它处于负位置(a1 -> b1) -> c1,在整个类型中处于负数位置。正 * 负 * 负 = 正,并且它是协变的。你明白了。)

现在,让我们来看看MonadIO class:

class Monad m => MonadIO m where
    liftIO :: IO a -> m a

我们可以将其视为子类型的显式声明:我们提供了一种方法来使IO a是一个子类型m a对于一些混凝土m。我们立刻就知道我们可以使用任何值IO构造函数处于积极位置并将它们变成ms。但仅此而已:我们没有办法变得消极IO构造函数进入ms——我们需要一个更有趣的类。

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

在 Haskell 中提升高阶函数 的相关文章

  • Haskell,堆栈:找到可执行文件

    我正在寻找类似的东西 stack whereis hasktags where whereis行为或多或少类似于 UNIXwhereis命令 hasktags是这样运行的 stack exec hasktags stack exec whe
  • 使用 FoldLine 解析多个块

    对于这个简化的问题 我试图解析一个如下所示的输入 foo bar baz quux woo hoo xyzzy glulx into foo bar baz quux woo hoo xyzzy glulx 我尝试过的代码如下 import
  • Haskell 中的尾递归字符串分割

    我正在考虑分割字符串的问题s在一个字符处c 这表示为 break c s 其中 Haskell 库定义break c 足够接近 br br s h t if c h then s else let h t br t in h h t 假设我
  • 简单 Haskell Monad - 随机数

    我正在尝试扩展代码这个帖子 https stackoverflow com questions 3944170 haskell and state 接受的答案 允许我能够基于以种子作为参数的函数 randomGen 调用 randomGen
  • 找不到模块“Yesod”

    我有以下代码 LANGUAGE TypeFamilies QuasiQuotes MultiParamTypeClasses TemplateHaskell OverloadedStrings module Simple where imp
  • 检查对以下内容的理解:“变量”与“变量” “价值”、“功能”与“抽象”

    这个问题是后续问题this one https stackoverflow com questions 25327705 is function a sort of variable 25329157 25329157在学习 Haskell
  • 不同编程语言中的浮点数学

    我知道浮点数学充其量可能是丑陋的 但我想知道是否有人可以解释以下怪癖 在大多数编程语言中 我测试了 0 4 到 0 2 的加法会产生轻微的错误 而 0 4 0 1 0 1 则不会产生错误 两者计算不平等的原因是什么 在各自的编程语言中可以采
  • 如何在不声明新数据的情况下更改类型(String,Int)元组的 Ord 实例?

    我正在尝试对类型列表进行排序 String Int 默认情况下 它按字符串排序 然后按整数排序 如果字符串相等 我希望它是相反的 首先比较整数 然后如果相等则比较字符串 另外 我不想切换到 Int String 我找到了一种通过定义实例来实
  • Haskell Data.Decimal 作为 Aeson 类型

    是否可以解析一个数据 十进制 https hackage haskell org package Decimal 0 4 2 docs Data Decimal html使用 Aeson 包从 JSON 获取 假设我有以下 JSON foo
  • 我是否需要采取明确的操作来促进与持久数据结构的共享?

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

    我要创建一个带有两个参数 字符串 的函数 该函数应查看第一个参数是否是第二个参数的子字符串 如果是这种情况 它将返回每个出现的元组 其中包含子字符串的起始索引和子字符串的结尾索引 例如 f String gt String gt Int I
  • 构造微积分中的“Refl”东西?

    在语言中 例如Agda Idris or Haskell对于类型扩展 有一个 键入类似于以下内容的内容 data a b where Refl a a a b意思是a and b是相同的 这样的类型可以定义在结构演算 https en wi
  • 在 Haskell 中获取玫瑰树的根

    最近我开始学习 Haskell 并在以下练习中遇到困难 Write functions root Rose a gt a and children Rose a gt Rose a that return the value stored
  • 使用带有两个列表而不是一个列表的地图。可以筑巢吗?

    我需要多次运行一个带有两个参数的函数 我有两个包含这些参数的列表 我希望能够使用map或类似的东西用相应的参数调用函数 我要调用的函数具有以下类型 runParseTest String gt String gt IO 列表的创建方式如下
  • Haskell 处理负参数

    尝试对两个值求和 其中只有一个为负值 例如 1 and 2 soma Float gt Float gt Float soma x1 x2 x1 x2 结果出现错误 为什么
  • Scala 函数定义参数列表中不同的括号样式

    Scala 中以下两个函数定义有什么区别 1 def sum f Int gt Int a Int b Int Int code 2 def sum f Int gt Int a Int b Int Int code SBT 的控制台 RE
  • 如何在 Haskell 中使 CAF 不是 CAF?

    如何将常量应用形式变成 而不是常量应用形式 以阻止它在程序的生命周期中保留 我尝试过这种方法 Dummy parameter to avoid creating a CAF twoTrues gt Bool twoTrues map Tru
  • 管道 - 将多个来源/生产者合并为一个

    我正在使用读取文件sourceFile 但我还需要在处理操作中引入随机性 我认为最好的方法是拥有一个这样的制片人 Producer m StdGen ByteString 其中 StdGen 用于生成随机数 我打算让生产者执行 source
  • 你将如何在 Haskell 中(重新)实现迭代?

    iterate a gt a gt a gt a 你可能知道 iterate是一个接受函数和起始值的函数 然后它将函数应用于起始值 然后将相同的函数应用于最后的结果 依此类推 Prelude gt take 5 iterate 2 2 2
  • 我可以从 GHCi 中找到 GHC 版本吗?

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

随机推荐

  • 如何传递对字符串的引用?

    我读过的所有内容scanf gets and fgets是它们有问题 带有空白 溢出或复杂性 我正在学习 C 课程简介 因为我有足够的 Java 和其他语言编程经验 所以我有信心这样做 所以我决定创建自己的函数来获取用户使用的字符串输入ge
  • 涉及 group by 和 join 的 SQL 查询

    我无法在标题部分更具体 但我想为我做一些有点复杂的事情 我以为我做到了 但事实证明这是有问题的 我有以下三个表 项目表 id项目 title idOwner 报价表 idOffer id项目 帐号 负责任的 帐号 Username Now
  • 我可以阻止接口的实现吗?

    我有以下情况 public interface A void doSomethingCool public interface B extends A void doSomethingVeryBCool public interface C
  • 等待用户完成 JavaScript 中 blob 的下载

    在 Javascript 中 我创建了许多 blob 我想提示用户将它们另存为文件 目前 我正在使用URL createObjectURL 将 URL 放入链接中 并模拟对该链接的点击 当然我打电话URL revokeObjectURL释放
  • 从 DWORD 到 64 位指针的类型转换警告

    旧的 32 位 C 应用程序 MS Visual Studio 的代码行如下 m value PUCHAR someDWORD 其中 PUCHAR 是指向无符号字符的指针 现在我已更改为 64 位 并且收到有关从 DWORD 转换为 64
  • RequireJS:为什么相对路径适用于define(),但不适用于require()?

    假设您有以下目录结构和以下文件 root require jquery js folder index html main js AnotherModule js 在 RequireJS 中 当您引用以 开头的模块时 RequireJS 会
  • 是否可以使用 PowerShell 获取 Azure 订阅优惠或 OfferId?

    是否可以使用 Powershell 获取 Azure 订阅优惠或 OfferId 通过门户 这将是订阅 gt 属性 gt 优惠或优惠 ID 我找了好久了 还是没看到 Thanks 现在可以使用资源图形浏览器通过类似于以下的查询从门户完成此操
  • 如何读取本地xml文件作为android中的输入流资源文件夹?

    我正在尝试从类似的东西获取输入流 InputSource myInputSource new InputSource activity getResources openRawResource com MYCLass R xml progr
  • 在邮递员帖子请求中发送地图

    当我希望它使用 RequestBody 注释直接映射到我的 Java pojo 时 我找不到关于如何在 json 帖子中格式化地图的好答案 我假设 json 看起来像这样 myInt 10 myMap 1 A 我的 pojo 会有一个myI
  • JS 代码在 codepen 上运行缓慢,但在本地运行良好

    我已经为无与伦比的井字游戏实现了极小极大算法 极小极大算法是递归的 执行大迭代 这对计算机来说并不大 只对人类来说大 第一步在 codepen 上执行大约需要 3 秒 但在我的本地计算机上立即执行 怎么了 我的代码效率不高吗 或者是code
  • Google Charts LineChart 自定义点

    是否可以添加一个自定义点形状到折线图 谷歌的自定义点文档没有提及任何有关添加他们尚未提供的形状的内容 我确实找到了这个类似的问题有一个很好的答案 但我不认为我可以使用 angular google chart 做到这一点 即使有可能 我也希
  • Javascript 对象 push() 函数

    我有一个 javascript 对象 我实际上通过 ajax 请求获取数据 var data 我在里面添加了一些东西 data 0 ID 1 Status Valid data 1 ID 2 Status Invalid 现在我想删除所有状
  • 将 Excel 转换为 PDF - Java 使用 iText

    我使用 Apache POI 创建了一个 excel 文件 现在我需要将其转换为 PDF 我想使用 iText 但我想将合并的单元格 样式等从 Excel 文件复制到 pdf 我怎样才能实现这个目标 因为我在网上找到的代码示例 使用 iTe
  • ruby、rails gem 安装错误 - 错误:执行 gem 时 ... (Encoding::UndefinedConversionError)

    我尝试使用 ruby 来使用上一个版本 但是当运行 gem install Rails 时 总是出现错误 ERROR While executing gem Encoding UndefinedConversionError U 041D
  • 检查 SQL Azure 中数据库是否存在

    谁能告诉我如何在 sql azure 中编码数据库是否存在 您是否尝试过查询 sys databases 表 这应该会给你你正在寻找的东西 更多信息here 注意 您需要针对 Master 数据库运行此查询 否则 您只会看到当前数据库 和主
  • 如何使用 Loki 的小对象分配器?

    我需要使用 Loki 的小对象分配器 但我对其工作原理感到非常困惑 我已经阅读了文档和很多论坛 但没有意义 其中一些人说使用 stl 其他人则使用自定义分配器 我只需要能够通过分配和取消分配不同大小的对象来测试其性能 有人可以提供一个如何使
  • java方法重载继承与多态

    这是我遇到的一个测试练习问题 非常感谢您帮助我理解这些概念 让 Hawk 成为 Bird 的子类 假设某个类有两个重载方法 void foo Hawk h 和 void foo Bird b 在调用 foo x 之后将执行哪个版本 声明 B
  • 为 GM 创建 JQueryscript - 重写 JS 代码带来的麻烦

    在尝试在没有帮助和有帮助的情况下解决问题之后 我仍然陷入困境 我的目标是用 JS 编写一个 GM 脚本 有人告诉我使用 jQuery 因为它很简单 嗯 我上周开始学习 JS 脑子里塞满了信息 我需要的是提示 开始 开始 任何告诉我如何将脚本
  • 如何选择具有指定条件的不同行

    假设有一张表 a 1 a 2 b 2 c 3 c 4 c 1 d 2 e 5 e 6 如何选择每组所有行的不同最小值 所以这里的预期结果是 a 1 b 2 c 1 d 2 e 5 EDIT 我的实际表包含更多列 我想全部选择它们 这些行仅在
  • 在 Haskell 中提升高阶函数

    我正在尝试构造一个类型的函数 liftSumthing a gt m b gt m b gt a gt t m b gt t m b where t是一个 Monad 转换器 具体来说 我有兴趣这样做 liftSumthingIO Mona