63

私はこのコードを持っていました:

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とGHC-7.4の「データ型プロモーション」ページに追加された新しい節が見つかりました。

コンストラクターが種多態的である、制約を伴う、または存在量化を使用するデータ型は昇格しません。

私の質問は:

  1. そのようなコンストラクターを宣伝しない理由は何ですか?
  2. それを行う正しい方法は何ですか?
4

1 に答える 1

1

どのバージョンの GHC 7.6 を使用しているか、どの拡張機能を使用しているかについては言及していませんでした。

このチケットはあなたの質問 1 に答えているようですが、私自身は問題を完全には理解していません。SSetあなたの特定の例では、その引数の1つ ( ) が制約Symbol tpeをもたらす関連型であるため、昇格できないと思います。SymbolSet

クラスの外に移動Symbolすると、型が昇格されますが、種類の不一致エラーが発生します。

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

に種類の署名を追加することで、シバン全体をコンパイルできます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

私はあなたのコードをよく理解していないので、うまくいかないかもしれません。

于 2014-02-14T23:10:13.787 に答える