检测Haskell中的冗余约束?

检测Haskell中的冗余约束?,haskell,constraints,ghc,Haskell,Constraints,Ghc,在Haskell中有没有检测冗余约束的方法 例如: class(aa,ba)=>c1a--c1a和B 实例(A,B A)=>c1a 等级(A、B、A、C)=>C2 A 实例(A、B、A)=>c2a f::(C1 a,C2 a)=>a f=。。。 这里,C2意味着C1,并且在f的签名中使用C1是多余的,即同义反复 在现实世界的元编程环境中,这将变得更为复杂,并将大大有助于消除信号头的混乱,以及帮助我理解和跟踪正在发生的事情 考虑到GHC的形式主义,这在逻辑上是可能的吗 GHC中是否有可用的基础结

在Haskell中有没有检测冗余约束的方法

例如:

class(aa,ba)=>c1a--c1a和B
实例(A,B A)=>c1a
等级(A、B、A、C)=>C2 A
实例(A、B、A)=>c2a
f::(C1 a,C2 a)=>a
f=。。。
这里,C2意味着C1,并且在
f
的签名中使用C1是多余的,即同义反复

在现实世界的元编程环境中,这将变得更为复杂,并将大大有助于消除信号头的混乱,以及帮助我理解和跟踪正在发生的事情

考虑到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, B 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, B a, C a) => C2 a
          -- Defined at test.hs:11: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
*Main
> :t x
x :: forall {a}. (A a, B a, C a) => a
>x=未定义::(c1a,c2a)=>a
:1:18:警告:[-wsimpilifiable类约束]
•约束“C1 a”匹配
例a。(A A,B A)=>C1 A——在试验中定义。hs:8:10
这使得内部绑定的类型推断变得脆弱;
要么使用MonolocalBind,要么使用实例简化它
•在表达式类型签名中:(C1 a,C2 a)=>a
在表达式中:未定义::(c1a,c2a)=>a
在“x”的方程式中:x=未定义::(c1a,c2a)=>a
:1:18:警告:[-wsimpilifiable类约束]
•约束“C2 a”匹配
例a。(A、B、A)=>c2a
--在试验中定义。hs:11:10
这使得内部绑定的类型推断变得脆弱;
要么使用MonolocalBind,要么使用实例简化它
•在表达式类型签名中:(C1 a,C2 a)=>a
在表达式中:未定义::(c1a,c2a)=>a
在“x”的方程式中:x=未定义::(c1a,c2a)=>a
*主要
>:t x
x::forall{a}。(A,ba,ca)=>A

本例中的前两个警告实际上只是一个愉快的意外,与存根的简单程度有关;你不可能总是得到它们。真正有趣的是第二个查询,
:tx
,它减少了对基本事实的约束,您需要了解关于
的有趣的

。正如您所说,我认为
-wsimpilifiable类约束在实践中不是很有用,举个例子,我以前从未见过它。
:t
技巧很有趣,但它只是给出了一组“规范”约束,而不是消除所提供的约束集中的冗余约束。@AriFordsham它确实消除了冗余约束。例如,
:t未定义::(Eq a,Ord a)=>a
产生
Ord a=>a
。事实上,即使在所示的示例中,它也没有盲目地将
C1
转化为
A、B
C2
转化为
A、B、C
——输出中没有重复的
A
B
约束。对,但它没有告诉我代码中哪些约束是多余的。我必须从该列表中手动重建复合约束(
C1
,在本例中)。@AriFordsham
C1
C2
都是冗余的,因为
A
B
C
更简单。-)可简化的约束实际上没有什么错。它们可以帮助记录。