我有这段代码:
class SymbolSet tpe where
data Symbol tpe :: *
data SSet tpe where
Identity :: tpe -> SSet tpe
And :: SSet tpe -> Symbol tpe -> SSet tpe
class HasElem a b 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
中的“数据类型提升”页面中添加了一个新条款
我们不推广构造函数是多态的数据类型, 涉及约束,或使用存在量化。
我的问题是:
答案 0 :(得分:1)
你没有说你正在使用哪个版本的GHC 7.6或包含你所使用的扩展名,所以我猜了一下。
This ticket似乎回答了你的问题1,虽然我自己并不完全理解这个问题。在您的特定示例中,我认为SSet
不可推销,因为它的一个参数(Symbol tpe
)是一个关联类型,它带来了SymbolSet
约束。
如果我将Symbol
移出课程,我们会获得提升类型,但现在我们会遇到错误的错误:
{-# 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
我真的不了解您的代码,因此可能对您不起作用。