数据构造器在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。
我的问题是:
- 不推广这种构造函数的理由是什么?
- 什么是正确的做法呢?
你没有说你使用的是哪个版本的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
我真的不明白你的代码,所以这可能不适合你。