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

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(使用前将#替换为@)

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

  • F# 中类型约束的顺序

    这适用于 F 4 0 type Something lt a b when b gt seq lt b gt gt 这不会 type Something lt b when b gt seq lt b gt a gt 类型名称中出现意外的符
  • 防止被 0 除的 Typescript 类型

    我正在使用打字稿创建一个用于培训目的的计算系统 但在除法过程中出现打字错误 您知道如何解决吗 type Variable value number resolve gt number type NoZeroVariable value Om
  • 将系统命令的结果绑定到 Haskell 中的变量

    如何在 Haskell 中运行系统命令and将其结果 即标准输出 绑定到变量 在伪 Haskell 中 我正在寻找类似以下内容的内容 import System Process main do output lt callCommand e
  • Haskell Cabal 包 - 找不到 Paths_ 模块

    我正在开发一个 Haskell 项目 Happstack 服务器 Blaze HTML 前端作为主要库 我想添加一个静态数据目录 看起来你可以使用 Cabal 使用自动生成的Path
  • 如何在不实例化一个类的情况下检查它是否继承了另一个类? [复制]

    这个问题在这里已经有答案了 假设我有一个如下所示的类 class Derived some inheritance stuff here 我想在我的代码中检查类似的内容 Derived is SomeType 但看起来像is运算符需要 De
  • 导入 Haskell 模块

    我是哈斯克尔的新手 为什么当我尝试使用时Days from Data Time我收到此错误 Could not find module Data Time It is a member of the hidden package time
  • 如何将对象转换为传递给函数的类型?

    这不会编译 但我想做的只是将对象转换为传递给函数的 t public void My Func Object input Type t t object ab TypeDescriptor GetConverter t ConvertFro
  • ErrorT 已弃用,但 exceptT 不适合

    我有一个一元计算 在某些时候 由于单子模式匹配 它开始需要 MonadFail 约束 我的简单解决方法是使用以下命令运行它 fmap either error id runErrorT 然而哎呀 Deprecated Use Control
  • 为什么 Parsec 的 sepBy 停止并且不解析所有元素?

    我正在尝试解析一些逗号分隔的字符串 该字符串可能包含也可能不包含具有图像尺寸的字符串 例如 hello world 300x300 good bye world 我写了下面的小程序 import Text Parsec import qua
  • Haskell scala 互操作性

    我是 Scala 初学者 来自面向对象范式 在了解 Scala 的函数式编程部分时 我被引导到 Haskell 纯函数式编程语言 探索 SO 问题答案 我发现 Java Haskell 具有互操作性 我很想知道 Scala Haskell
  • Haskell:无法预期类型“Integer”与实际类型“Int”

    我已经盯着这段代码有一段时间了 但我无法理解该错误消息 divisors Integer gt Integer divisors n t t lt 1 n mod n t 0 length a gt Integer length 0 len
  • 您可以传递“类型”作为参数吗?

    我想在 VB NET 中做类似以下的事情 可以吗 Function task value as Object toType as Type Return DirectCast value toType End Function 是的 有系统
  • Haskell:是的,没有类型类。为什么是整数?

    我有一个关于 GHCi 如何假定整数类型的问题 我正在阅读 Learn you a Haskell 是 否类型的课程 如果您想阅读全文 这里有一个链接 http learnyouahaskell com making our own typ
  • Scala:如何将可变参数指定为类型?

    代替 def foo configuration String String 我希望能够写 type Configuration String String def foo configuration Configuration 主要用例是
  • Haskell 中的分类结构

    Hask通常被认为是一个范畴 其对象是类型 态射是函数 然而 我看到 Conor McBride pigworker 警告不要使用Hask多次 1 https stackoverflow com a 45905082 474311 2 ht
  • 具有上限的联合类型

    我正在遵循这个问题的公认答案中提出的技术如何定义 类型析取 联合类型 https stackoverflow com questions 3508077 does scala have type disjunction union type
  • 使用 FoldLine 解析多个块

    对于这个简化的问题 我试图解析一个如下所示的输入 foo bar baz quux woo hoo xyzzy glulx into foo bar baz quux woo hoo xyzzy glulx 我尝试过的代码如下 import
  • Haskell 中列表列表的笛卡尔积

    给定一个长度列表的列表x所有子列表的长度都相同y 输出y x长度列表x包含每个子列表中的一项 例子 x 3 y 2 1 2 3 4 5 6 Output 2 3 8不同的输出 1 3 5 1 4 5 1 3 6 1 4 6 2 3 5 2
  • Powershell日期类型无法找到

    我正在尝试使用PowerShell连接virustotal API 代码来自virustotal网站 我得到 无法找到类型 System Security Cryptography ProtectedData 错误信息 代码如下 funct
  • Haskell 入门

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 几天来 我一直试图理解 Haskell 中的函数式编程范例 我通过阅读教程和观看截屏视频

随机推荐

  • 网格布局+滚动视图

    我想创建一个像 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