以下是完全可编辑的代码:
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
?有可能吗?如果不是那么为什么?
答案 0 :(得分:3)
添加一个独立的派生Typeable1
实例,如下面的代码所示,已经解决了这个问题,但我没有解释为什么会这样,所以问题仍然存在。
data family DF a
deriving instance Typeable1 DF
data instance DF Int = DFInt deriving (Show)
data instance DF Char = DFChar deriving (Show)
答案 1 :(得分: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