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

3

添加一个独立的派生Typeable1实例,如下面的代码,已经解决了这个问题,但我没有解释为什么会这样,所以这个问题仍然悬而未决。

data family DF a
deriving instance Typeable1 DF
data instance DF Int = DFInt deriving (Show)
data instance DF Char = DFChar deriving (Show)
于 2013-08-03T22:17:07.553 回答
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 回答