如何解决在 Haskell 中检测冗余约束?
有没有办法检测 Haskell 中的冗余约束?
例如:
class (A a,B a) => C1 a -- C1 ~ A AND B
instance (A a,B a) => C1 a
class (A a,B a,C a) => C2 a
instance (A a,C a) => C2 a
f :: (C1 a,C2 a) => a
f = ...
这里,C2 意味着 C1,并且在 f
的签名中使用 C1 是多余的,即重言式。
在现实世界的元编程情况下,这会waaaay 更加复杂,并且将显着帮助整理签名头,并帮助我理解和跟踪正在发生的事情。
考虑到 GHC 的形式主义,这在逻辑上是否可行?
GHC 内的基础设施是否可用?
解决方法
如果我把你的存根放在一个文件中:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
class A a
class B a
class C a
class (A a,B a) => C1 a -- C1 ~ A AND B
instance (A a,B a) => C1 a
class (A a,B a,C a) => C2 a
instance (A a,C a) => C2 a
然后您可以通过将变量绑定到 undefined
以及您想在 ghci 中减少的类型来了解冗余约束:
> x = undefined :: (C1 a,C2 a) => a
<interactive>:1:18: warning: [-Wsimplifiable-class-constraints]
• The constraint ‘C1 a’ matches
instance forall a. (A a,B a) => C1 a -- Defined at test.hs:8:10
This makes type inference for inner bindings fragile;
either use MonoLocalBinds,or simplify it using the instance
• In an expression type signature: (C1 a,C2 a) => a
In the expression: undefined :: (C1 a,C2 a) => a
In an equation for ‘x’: x = undefined :: (C1 a,C2 a) => a
<interactive>:1:18: warning: [-Wsimplifiable-class-constraints]
• The constraint ‘C2 a’ matches
instance forall a. (A a,C a) => C2 a
-- Defined at test.hs:11:10
This makes type inference for inner bindings fragile;
either use MonoLocalBinds,C2 a) => a
*Main
> :t x
x :: forall {a}. (A a,C a) => a
这种情况下的前两个警告实际上只是一个愉快的意外,与您的存根有多简单有关;你不会总是得到它们。真正有趣的是第二个查询 :t x
,它减少了对您需要了解的关于 a
的基本事实的限制。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。