Haskell 为什么我会得到一个“;约束匹配实例声明“;错误?
我有以下例子:Haskell 为什么我会得到一个“;约束匹配实例声明“;错误?,haskell,Haskell,我有以下例子: instance(Typeable crypto,ToCBOR(SIPHash crypto))=>ToCBOR(SIP crypto),其中 -- ... 实例(可键入加密,ToCBOR(哈希加密SIPData))=>ToCBOR(SIPHash加密),其中 -- ... 这会导致以下错误: • The constraint ‘ToCBOR (SIPHash crypto)’ matches an instance declaration instance (Ty
instance(Typeable crypto,ToCBOR(SIPHash crypto))=>ToCBOR(SIP crypto),其中
-- ...
实例(可键入加密,ToCBOR(哈希加密SIPData))=>ToCBOR(SIPHash加密),其中
-- ...
这会导致以下错误:
• 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:我还尝试在没有任何运气的情况下删除了
可键入加密
约束,我想这是因为编译器没有查看实例声明的LHS。本质上,Haskell告诉您,正如所写的,这些实例将使某些类型的类型推断无法正常工作。monocalbinds
语言扩展更改了类型系统处理这些场景的方式,因此启用它将允许您的实例按编写的方式运行,但可能会更改代码的语义
Haskell通常对受let
或where
约束的变量使用最通用(最多态)的解释,但如果允许这些类型的实例,可能会有多种不同但同样通用的解释MonolocalBind
将导致解析器使用不太通用的解释,而不是陷入停顿或做出任意决定。有一篇文章更全面地解释了这个问题,尽管我承认,我没有时间坐下来读它
正如@chi所指出的,GHC让您知道,通过将您的第一个实例替换为:
instance (Typeable crypto, ToCBOR (Hash crypto SIPData)) => ToCBOR (SIP crypto)
我猜这促使你写
实例(可键入密码,ToCBOR(Hash crypto SIPData))=>ToCBOR(SIP crypto)
。在这种情况下,您可以从第二个实例中免费获得ToCBOR(SipHash crypto)
。这就是我最后做的。我使用了ConstraintKinds
来避免重复约束:键入siphascborrept=(Typeable t,ToCBOR(Hash t SIPData))
。