为什么会出现“约束匹配即时声明”错误?

时间:2019-11-15 15:07:01

标签: 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。

1 个答案:

答案 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通常使用受MonoLocalBindslet约束的变量的最通用(最多态)解释,但是如果允许这些实例,则可能会有多种不同但同样通用的实例,解释。 where将使解析器使用一种不太笼统的解释,而不是暂停或做出任意决定。有一个80-page paper from Vytiniotis, et al可以更全面地解释这个问题,尽管诚然,我没有时间坐下来阅读它。

正如@chi所指出的那样,GHC告诉您可以通过将第一个实例替换为以下内容来完全避免此问题(在这种情况下):

MonoLocalBinds