数据系列和可输入数据

时间:2013-08-03 22:06:35

标签: haskell

以下是完全可编辑的代码:

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?有可能吗?如果不是那么为什么?

2 个答案:

答案 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