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

rab*_*isg 63 constructor haskell 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
Run Code Online (Sandbox Code Playgroud)

这是在GHC-7.4中编译的.但是,在转向GHC-7.6时,它开始出现编译错误:

'And' of tpe `forall tpe. tpe -> Symbol * tpe -> SSet tpe' is not promotable
Run Code Online (Sandbox Code Playgroud)

在挖掘文档时,我发现在GHC-7.6GHC-7.4的 "数据类型升级"页面中添加了一个新的条款

我们不会提升其构造函数是多态的,涉及约束或使用存在量化的数据类型.

我的问题是:

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

jbe*_*man 1

您没有说明您使用的是哪个版本的 GHC 7.6,也没有包括您使用的扩展,所以我猜测了一下。

这张票似乎回答了你的问题1,尽管我自己并不完全理解这个问题。在您的特定示例中,我认为SSet不可升级,因为它的参数之一 ( Symbol tpe) 是一个关联类型,它带来了SymbolSet约束。

如果我Symbol离开班级,我们会得到类型提升,但是现在我们会得到类型不匹配错误:

{-# LANGUAGE DataKinds , TypeFamilies , GADTs , MultiParamTypeClasses #-}
class SymbolSet tpe where
  -- data Symbol tpe :: *
data Symbol tpe :: *
-- ...
Run Code Online (Sandbox Code Playgroud)

我可以通过添加类型签名来编译整个 shebang HasElem

{-# 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
Run Code Online (Sandbox Code Playgroud)

我不太理解你的代码,所以这可能不适合你。