haskell - 为什么我会收到“约束匹配实例声明”错误?
问题描述
我有以下情况:
instance (Typeable crypto, ToCBOR (SIPHash crypto)) => ToCBOR (SIP crypto) where
-- ...
instance (Typeable crypto, ToCBOR (Hash crypto SIPData)) =>ToCBOR (SIPHash crypto) where
-- ...
这会导致以下错误:
• The constraint ‘ToCBOR (SIPHash crypto)’
matches an instance declaration
instance (Typeable crypto, ToCBOR (Hash crypto SIPData)) =>
ToCBOR (SIPHash crypto)
-- Defined at src/Cardano/Ledger/Spec/STS/Update/Data.hs:383:10
This makes type inference for inner bindings fragile;
either use MonoLocalBinds, or simplify it using the instance
• In the context: (Typeable crypto, ToCBOR (SIPHash crypto))
While checking an instance declaration
In the instance declaration for ‘ToCBOR (SIP crypto)’
为什么我会收到此错误,编译器错误所指的“匹配”是什么?(据我所见,约束是不同的)。
PS:我也尝试在Typeable crypto
没有任何运气的情况下删除约束,我猜这是由于编译器没有查看实例声明的 LHS。
解决方案
从本质上讲,Haskell 是在告诉您,正如所写的那样,这些实例将使您通常认为不可能工作的某些类型推断成为可能。语言扩展改变了类型系统处理这些场景的MonoLocalBinds
方式,因此启用它将使您的实例能够按照编写的方式运行,但可能会改变代码的语义。
let
Haskell 通常对由or绑定的变量使用最一般(最多态)的解释where
,但如果您允许这些类型的实例,可能会有多种不同但同样普遍的解释。MonoLocalBinds
将导致解析器使用不太一般的解释,而不是停止或做出任意决定。Vytiniotis 等人有一篇长达 80 页的论文更全面地解释了这个问题,尽管不可否认,我没有时间坐下来阅读它。
正如@chi 指出的那样,GHC 让您知道,您可以完全避免这个问题(在这种情况下),方法是将您的第一个实例替换为:
instance (Typeable crypto, ToCBOR (Hash crypto SIPData)) => ToCBOR (SIP crypto)
推荐阅读
- spring-security - Gatling 测试 CSRF Spring Security 通过 Web 表单阻止了我的帖子
- android - Android Studio 无法识别 .kt 文件
- c# - 检查负数是否在一个范围内
- xamarin - 如何对 xamarin 表单应用程序进行基准测试
- c++ - bazel-run 不会加载在 bazel 构建时加载的所有 tensorflow 包
- xml - 如何在 Oracle 中从 Clob XML 中查找节点值
- javascript - 断言数组中的值已在下拉列表中签入
- javascript - 如何从 Datpicker 中的代码更改时间?
- java - Antisamy 在脚本标记后删除字符串
- xslt - 如何在撒克逊人中做 xsl:include over https?