数据构造器在GHC-7.6中的推广

我有这样的代码:

class SymbolSet tpe where data Symbol tpe :: * data SSet tpe where Identity :: tpe -> SSet tpe And :: SSet tpe -> Symbol tpe -> SSet tpe class HasElem ab where instance (SymbolSet tpe) => HasElem (And (Identity tpe) s) s instance (HasElem sset s) => HasElem (And sset s) s 

正在编写GHC-7.4。 然而,在转向GHC-7.6时,开始出现编译错误:

 'And' of tpe `forall tpe. tpe -> Symbol * tpe -> SSet tpe' is not promotable 

在挖掘文档时,我发现在GHC-7.6和GHC-7.4中的 “数据types促进”页面添加了一个新的条款

我们不推广其构造函数是多态的,涉及约束的,或使用存在量化的数据types。

我的问题是:

  1. 不推广这种构造函数的理由是什么?
  2. 什么是正确的做法呢?

你没有说你使用的是哪个版本的GHC 7.6,或者包括你有哪些扩展,所以我猜测了一下。

这张票似乎回答你的问题1,虽然我自己并不完全明白这个问题。 在你的具体例子中,我认为SSet是不可SSet因为它的一个参数( Symbol tpe )是一个与SymbolSet约束相关的关联types。

如果我把Symbol从类中移出来,我们得到了types的提升,但是现在我们得到了种类不匹配的错误:

 {-# LANGUAGE DataKinds , TypeFamilies , GADTs , MultiParamTypeClasses #-} class SymbolSet tpe where -- data Symbol tpe :: * data Symbol tpe :: * -- ... 

我可以通过向HasElem添加类签名来获得整个shebang的编译:

 {-# LANGUAGE DataKinds , TypeFamilies , GADTs , MultiParamTypeClasses, FlexibleInstances #-} class SymbolSet tpe where -- MOVED OUT OF CLASS: data Symbol tpe :: * data SSet tpe where Identity :: tpe -> SSet tpe And :: SSet tpe -> Symbol tpe -> SSet tpe -- ADDED KIND SIGNATURES: class HasElem (a :: SSet *) (b :: Symbol *) where instance (SymbolSet tpe) => HasElem (And (Identity tpe) s) s instance (HasElem sset s) => HasElem (And sset s) s 

我真的不明白你的代码,所以这可能不适合你。