我有以下情况:
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。
答案 0 :(得分:1)
从本质上讲,Haskell告诉您,按照书面形式,这些实例将进行某些通常可能无法工作的类型推断。 Build file '/Users/cfouts/git-repos/zift/ziftsolutions/rest-common/build.gradle' line: 34
* What went wrong:
A problem occurred evaluating project ':rest-common'.
> Cannot change dependencies of configuration ':rest-common:testRuntime' after it has been resolved.
语言扩展更改了类型系统处理这些情况的方式,因此启用该扩展将允许您的实例按书面形式运行,但可能会更改代码的语义。
Haskell通常使用受MonoLocalBinds
或let
约束的变量的最通用(最多态)解释,但是如果允许这些实例,则可能会有多种不同但同样通用的实例,解释。 where
将使解析器使用一种不太笼统的解释,而不是暂停或做出任意决定。有一个80-page paper from Vytiniotis, et al可以更全面地解释这个问题,尽管诚然,我没有时间坐下来阅读它。
正如@chi所指出的那样,GHC告诉您可以通过将第一个实例替换为以下内容来完全避免此问题(在这种情况下):
MonoLocalBinds