3

以下は、完全にコンパイル可能なコードです。

data family DF a
data instance DF Int = DFInt deriving (Show)
data instance DF Char = DFChar deriving (Show)

ただし、次のように派生しようとするTypeableと、「インスタンス宣言が重複しています」というエラーが発生します。

data family DF a
data instance DF Int = DFInt deriving (Typeable)
data instance DF Char = DFChar deriving (Typeable)

Typeableでは、データ ファミリをどのように導出するのでしょうか。それはまったく可能ですか?そうでない場合、なぜですか?

4

2 に答える 2

1

を使用した派生の出力を-ddump-deriv見ると、各データ ファミリ インスタンス宣言が同一の を生成していたことがわかりますinstance Typeable1 DF

data family DF a
data instance DF Int = DFInt deriving (Typeable)
data instance DF Char = DFChar deriving (Typeable)

与える

instance Data.Typeable.Internal.Typeable1 Main.DF where
  Data.Typeable.Internal.typeOf1 _
    = Data.Typeable.Internal.mkTyConApp
        (Data.Typeable.Internal.mkTyCon
           17188516606402618172## 4748486123618388125## "main" "Main" "DF")
        []

instance Data.Typeable.Internal.Typeable1 Main.DF where
  Data.Typeable.Internal.typeOf1 _
    = Data.Typeable.Internal.mkTyConApp
        (Data.Typeable.Internal.mkTyCon
           17188516606402618172## 4748486123618388125## "main" "Main" "DF")
        []

したがって、このタイプの派生は、実際にやりたいことを行っているわけではありませんTypeable1。つまり、インスタンスではなくファミリを派生させています。しかし、その後、おそらく必要なものinstance (Typeable1 s, Typeable a) => Typeable (s a)は組み込みです。

data family DF a
deriving instance Typeable1 DF
data instance DF Int = DFInt deriving (Show)
data instance DF Char = DFChar deriving (Show)

data DFAll = forall a . Typeable a => DFAll (DF a)

toDFA :: Typeable a => DF a -> DFAll
toDFA = DFAll

fromDFA :: Typeable a => DFAll -> Maybe (DF a)
fromDFA (DFAll x) = cast x

*Main> fromDFA (toDFA DFInt) :: Maybe (DF Int)
Just DFInt 
于 2013-08-04T04:06:32.597 に答える