GHC-7.6中的数据构造函数升级

时间:2013-11-09 11:55:24

标签: haskell constructor ghc

我有这段代码:

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

在挖掘文档时,我发现在GHC-7.6 vs GHC-7.4

中的“数据类型提升”页面中添加了一个新条款
  

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

我的问题是:

  1. 不推广此类构造函数背后的理由是什么?
  2. 这样做的正确方法是什么?

1 个答案:

答案 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

我真的不了解您的代码,因此可能对您不起作用。