约束消失的情况:更高等级类型的怪异

2024-04-04

下面描述的所有实验都是使用 GHC 8.0.1 完成的。

这个问题是后续问题具有类型别名混淆的 RankNTypes https://stackoverflow.com/q/40252867/2751851。那里的问题归结为像这样的函数类型......

{-# LANGUAGE RankNTypes #-}

sleight1 :: a -> (Num a => [a]) -> a
sleight1 x (y:_) = x + y

...被类型检查器拒绝...

ThinAir.hs:4:13: error:
    * No instance for (Num a) arising from a pattern
      Possible fix:
        add (Num a) to the context of
          the type signature for:
            sleight1 :: a -> (Num a => [a]) -> a
    * In the pattern: y : _
      In an equation for `sleight1': sleight1 x (y : _) = x + y

...因为更高阶的约束Num a 不能移动到第二个参数的类型之外 https://stackoverflow.com/a/14593131/2751851(如果我们有的话就有可能a -> a -> (Num a => [a])反而)。既然如此,我们最终尝试为整个事情已经量化的变量添加一个更高等级的约束,即:

sleight1 :: forall a. a -> (Num a => [a]) -> a

完成这个重述后,我们可能会尝试稍微简化一下这个例子。我们来替换一下(+)用不需要的东西Num,并将有问题的参数的类型与结果的类型分开:

sleight2 :: a -> (Num b => b) -> a
sleight2 x y = const x y

这不像以前那样工作(除了错误消息中的细微变化):

ThinAir.hs:7:24: error:
    * No instance for (Num b) arising from a use of `y'
      Possible fix:
        add (Num b) to the context of
          the type signature for:
            sleight2 :: a -> (Num b => b) -> a
    * In the second argument of `const', namely `y'
      In the expression: const x y
      In an equation for `sleight2': sleight2 x y = const x y
Failed, modules loaded: none.

Using const然而,这里可能是不必要的,所以我们可以尝试自己编写实现:

sleight3 :: a -> (Num b => b) -> a
sleight3 x y = x

令人惊讶的是,这确实有效!

Prelude> :r
[1 of 1] Compiling Main             ( ThinAir.hs, interpreted )
Ok, modules loaded: Main.
*Main> :t sleight3
sleight3 :: a -> (Num b => b) -> a
*Main> sleight3 1 2
1

更奇怪的是,似乎并没有真正的Num对第二个参数的约束:

*Main> sleight3 1 "wat"
1

我不太确定如何使其易于理解。也许我们可以这么说,就像我们可以杂耍一样undefined只要我们从不评估它,一个不可满足的约束就可以很好地保留在类型中,只要它不用于右侧任何地方的统一。然而,这感觉像是一个相当弱的类比,特别是考虑到我们通常理解的非严格性是一个涉及值而不是类型的概念。此外,这并没有让我们更接近于理解世界是如何发生的。StringNum b => b——假设这样的事情真的发生了,但我完全不确定。那么,当约束似乎以这种方式消失时,对正在发生的情况的准确描述是什么?


哦,事情变得更奇怪了:

Prelude> sleight3 1 ("wat"+"man")
1
Prelude Data.Void> sleight3 1 (37 :: Void)
1

看那边is一个实际的Num对该论点的限制。只是,因为(正如 chi 已经评论的那样)b处于协变位置,这不是您在调用时必须提供的约束sleight3。相反,您可以选择任何类型b,那么无论它是什么,sleight3将提供一个Num举个例子吧!

嗯,显然那是假的。sleight3 can't为字符串提供这样的 num 实例,并且绝对不是为Void。但它也没有actually需要,因为就像你说的那样,应用该约束的参数永远不会被评估。回想一下,约束多态值本质上只是字典参数的函数。sleight3只是承诺在实际使用之前提供这样一本字典y,但随后它doesn't use y无论如何,所以没关系。

它基本上与这样的函数相同:

defiant :: (Void -> Int) -> String
defiant f = "Haha"

同样,参数函数显然不可能产生一个Int因为不存在Void对其进行评估的价值。但这也不是必需的,因为f根本就被忽略了!

相比之下,sleight2 x y = const x y有点用y:第二个参数const只是一个 0 级类型,因此编译器需要在此时解析任何所需的字典。即使const最终也抛出y即使这样,它仍然“强制”足够多的值,以表明它的类型不正确。

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

约束消失的情况:更高等级类型的怪异 的相关文章

  • 我们不应该使用单子绑定来使用循环写下 mfix 的情况

    我一直在尝试写mfix向下使用Control Arrow loop https hackage haskell org package base 4 14 0 0 docs src Control Arrow html loop 我想出了不
  • 应用交换律

    带有效果的应用程序编程 http staff city ac uk ross papers Applicative html麦克布莱德和帕特森的论文提出了互换法 u lt gt pure x pure f gt f x lt gt u 为了
  • 副作用是纯函数中找不到的一切吗?

    可以肯定地说 以下二分法成立 每个给定的函数是 要么纯粹 或有副作用 如果是这样 函数的 副作用就是纯函数中找不到的任何东西 这很大程度上取决于您选择的定义 可以公平地说 函数是pure or impure 纯函数始终返回相同的结果并且不会
  • 如何在 Kotlin 中正确处理大于 127 的 Byte 值?

    假设我有一个带有变量的 Kotlin 程序b类型的Byte 外部系统向其中写入大于的值127 外部 意味着我无法更改它返回的值的类型 val a Int 128 val b Byte a toByte Both a toByte and b
  • 如何在 Haskell 中枚举递归数据类型?

    这篇博文 http lukepalmer wordpress com 2008 05 02 enumerating a context free language 对于如何使用 Omega monad 对角枚举任意语法有一个有趣的解释 他提
  • SSIS Excel 导入强制错误的列类型

    我正在尝试使用 SSIS 将电子表格导入到我们的数据库中 由于某种原因 当其中两列包含字符数据时 SSIS 希望相信它们的类型为 Double 我尝试将列重新映射为 nvarchar 255 但它仍然不想选择它认为是双精度的数据 因为其中有
  • Haskell 中的常量变量声明

    要声明常量变量 我可以在 Ruby 中执行以下操作 class COLOR RED 10 BLUE 20 GREEM 30 end COLOR RED回报10 COLOR BLUE回报20 等等 我如何在 Haskell 中实现这一点 我想
  • 谁能解释一下 GHC 对 IO 的定义吗?

    标题非常自我描述 但有一个部分引起了我的注意 newtype IO a IO State RealWorld gt State RealWorld a 剥离newtype 我们得到 State RealWorld gt State Real
  • “反向”使用 Maybe Monad

    假设我有很多功能 f a gt Maybe a g a gt Maybe a h a gt Maybe a 我想按以下方式组合它们 如果 f 返回 Nothing 则计算 g 如果 g 返回 Nothing 则计算 h 如果其中任何一个计算
  • 计算两点之间的距离(Haskell)

    给定两个元组的输入 我希望能够使用以下公式计算两点之间的距离 距离 sqrt x1 x2 2 y1 y2 2 所以我希望函数调用和输出如下所示 gt distance 5 10 3 5 5 385 当我尝试运行下面的代码时 它告诉我输入 w
  • 如何找到仅是 2、3 和 5 的幂的倍数的所有数字的列表? [复制]

    这个问题在这里已经有答案了 I am trying to generate a list of all multiples which can be represented by the form where a b and c are w
  • 我应该使用镜头中的什么来按索引构建只读吸气剂?

    我有一个内部细节被隐藏的类型 我想提供某种镜头 可以在特定索引处读取所述类型的元素 但是not修改它们 一个Ixed我的类型的实例似乎没有做我想要的事情 因为它明确允许修改 尽管不允许插入或删除 如果我想允许只读索引 我不确定我使用什么 如
  • Haskell 测量函数性能

    在 Haskell 中 我如何 简单地 测量函数的性能 例如 运行需要多长时间 或者需要多少内存 我知道分析 但是 是否有一种更简单的方法不需要我对代码进行太多更改 测量运行需要多长时间以及需要多少内存是两个独立的问题 即 基准测试和分析
  • 带有查询参数的渲染 url

    无法找到简单问题的解决方案 答案应该是显而易见的 如何在 hamlet 模板中使用查询参数渲染 url I e ItemsR 将生成http localhost 3000 items我如何生成类似的东西http localhost 3000
  • 在 Haskell 命令行应用程序中提示输入密码

    以下 Haskell 程序提示用户在终端中输入密码 如果输入正确则继续 main do putStrLn Password password lt getLine case hash password member database of
  • java中获取HashMap中的变量类型

    我有一个HashMap
  • 地图不是接受一个函数而列表返回一个列表吗?

    map2 List a gt b gt c gt a gt b gt c map2 List f map2 List f a as bs map f a bs map2 List f as bs 这是我的讲座中的一个示例 它尝试将二元函数应
  • TypeScript 中泛型的不安全隐式转换

    TypeScript 编译器tsc编译以下代码 即使使用 strict旗帜 然而 该代码包含一个基本错误 而在 Java 或 C 等语言中可以避免这种错误 interface IBox
  • Typescript:隐式无参数函数类型

    我想要作为参数给出的函数的限定类型 我希望这种类型要么是一个没有参数的函数 返回一个包含参数的 void 函数 动作 要么是它返回自身的 void 函数 这是我想使用的代码 interface JsonArray extends Array
  • Haskell 类型定义,=> 等

    我正在使用 Learn You a Haskell 来学习 Haskell 第 54 页上有一个 像这样执行 take Num i Ord i gt i gt a gt a take n n lt 0 take take n x xs x

随机推荐

  • 网格布局+滚动视图

    我想创建一个像 Android 市场首页一样的布局 我正在尝试使用网格布局 因为我想放置不同大小和位置的图像视图 我还需要输入滚动视图 实际上我的问题是如何在 android support v7 widget GridLayout 中输入
  • 使用kableExtra的kbl()和save_kable()将表导出为word表到word文档?

    有没有办法在 R 脚本 而不是 R 标记 中将表格直接导出或编织为单词格式 knitr and kableExtra似乎提供了多种保存表格的选项 但没有将表格导出为实际 Word 文件的选项 library tidyverse librar
  • Java 可运行队列

    我需要对下面的关键代码进行同行评审 该类维护一个可运行对象的队列 并确保它们按顺序执行 即在前一个对象完成后开始一个新的任务 直到队列中没有更多任务为止 我很确定它确实如此 但我必须绝对确定它的行为符合预期 非常感谢 public fina
  • 建议对古式拼写进行其他查询(例如 Google 的 Did You Mean)

    我的客户有一个包含 400 年历史的房地产记录数据库 他们有兴趣根据他们的数据向用户提供替代拼写建议 我假设在这样的情况下 它会变成一个包含 Martin 行以及 Martyn 和 Martine 等建议的表 有谁知道可以索引其数据的第三方
  • Git - 删除像它一样的旧提交,并且它的更改从未发生过

    我想删除较旧的提交 因为我必须将其分成 2 个提交 所以变化是在a5b4cd与以下的变化相同2a0d40e a8bb836 2a0d40e Add sending a8bb836 Add parsing a5b4cbd Add sendin
  • 使用 Python 图像库 (PIL) 标准化一组图像的直方图(亮度和对比度)

    我有一个脚本 它使用 Google Maps API 下载一系列大小相等的方形卫星图像并生成 PDF 图像需要事先旋转 我已经使用 PIL 这样做了 我注意到 由于光线和地形条件不同 有些图像太亮 有些图像太暗 生成的pdf结果有点难看 在
  • Redis多插入问题

    我尝试多次插入 但它给了我错误 http pastie org 7337421 http pastie org 7337421 cat mass insert txt 3 r n 3 r nSET r n 3 r nkey r n 5 r
  • Ansible:SSH 错误:unix_listener:对于 Unix 域套接字来说太长

    这是一个已知问题 我找到了解决方案 但它对我不起作用 首先我有 fatal openshift node compute e50xx gt SSH Error ControlPath too long It is sometimes use
  • Maven Wagon 插件:wagon:upload 可以上传到多个位置吗?

    我正在调查Maven 旅行车插件 http mojo codehaus org wagon maven plugin 尝试将一些工件上传到远程 UNC Server 共享 servername share directory to put
  • 获取异步函数的 NULL 值(使用等待之后),然后更新为新值

    当我运行我的应用程序时 它会抛出很多错误 并且我的设备上会出现红色 黄色错误屏幕 它会自动刷新并向我显示预期的输出 从日志中我可以看到 首先我的对象返回为 null 随后以某种方式更新并获得输出 我最近开始了 Android 开发 Flut
  • 如何在android中处理搜索视图的后退按钮

    我开发了一个在操作栏中具有搜索视图的应用程序 当我完美搜索其过滤器时 我遇到了问题 但是当我按下后退按钮时 它仍然显示过滤器数据 所以我的问题是操作栏搜索的后退按钮的事件是什么看法 我的搜索视图代码是 SearchView searchVi
  • 具有架构组件的多模块导航

    所以我当前的应用程序中的模块有这样的结构 我还没有找到任何关于多模块导航的官方文档 但我发现了这个article https medium com hartwich daniel multi module navigation with t
  • 如何将列标题转换为贷款号码的行[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我陷入了无法旋转的境地 我有一个类似下面 temp 的表 使用sql server 2008 r2 Select LoanNumber 2
  • 维护和重用现有的 webdriver 浏览器实例 - java

    基本上每次我从 eclipse 运行 java 代码时 webdriver 都会启动一个新的 ie 浏览器并在大部分情况下成功执行我的测试 然而 我有很多测试要运行 而且 webdriver 每次都会启动一个新的浏览器会话 这很痛苦 我需要
  • Raspberry Pi 上的 Sqlite4java

    我想在 Raspberry Pi 上使用我的 java 项目 此代码依赖于 sqlite4java 它使用许多平台 包括 Arm 处理器 的本机实现link http code google com p sqlite4java downlo
  • 如何让 vscode 知道 SCM 何时可见?

    我想用 VScode 的键绑定制作切换键 使用 alt 1 到 5 切换资源管理器和搜索 scm 调试扩展 我可以找到 explorerViewletVisible 或 searchViewletVisible 但我找不到 scm 源代码控
  • 如何从 Angular 范围中排除元素?

    我的前提是错误的 虽然 AngularJS 确实减慢了速度 但这并不是因为我下面描述的问题 然而 正是 flim 对我的问题 如何从 Angular 范围中排除元素 的回答才证明了这一点 我正在构建一个网站 该网站使用 d3 Raphael
  • PhoneGap iOS 7 和 localStorage

    我目前正在构建一个 PhoneGap 3 3 0 iOS 应用程序 该应用程序使用 Ember js EmberData 和 LocalStorage 适配器来保存数据 读了一些文章后就像这个 StackOverflow 问题 https
  • 集合接口和WCF

    我正在使用 C 和 WCF 来做 Web 服务 我有一个实现 IEnumerable 的类的成员变量 我尝试通过执行以下操作将其序列化为我的数据合同的一部分 DataContract class Item DataMember privat
  • 约束消失的情况:更高等级类型的怪异

    下面描述的所有实验都是使用 GHC 8 0 1 完成的 这个问题是后续问题具有类型别名混淆的 RankNTypes https stackoverflow com q 40252867 2751851 那里的问题归结为像这样的函数类型 LA