Haskell 数据族和可类型化

Haskell 数据族和可类型化,haskell,Haskell,以下是一段完全可编译的代码: data family DF a data instance DF Int = DFInt deriving (Show) data instance DF Char = DFChar deriving (Show) 但是,尝试按以下方式导出可键入的会出现“重复实例声明”错误: 那么,如何为数据族派生Typeable?有可能吗?如果不是,那么原因是什么?添加独立的派生Typeable1实例(如以下代码)解决了问题,但我没有解释为什么这样做,因此问题仍然悬而未决 d

以下是一段完全可编译的代码:

data family DF a
data instance DF Int = DFInt deriving (Show)
data instance DF Char = DFChar deriving (Show)
但是,尝试按以下方式导出可键入的
会出现“重复实例声明”错误:


那么,如何为数据族派生
Typeable
?有可能吗?如果不是,那么原因是什么?

添加独立的派生
Typeable1
实例(如以下代码)解决了问题,但我没有解释为什么这样做,因此问题仍然悬而未决

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

如果使用
-ddump deriv
查看派生的输出,您会发现每个数据族实例声明都生成了相同的
实例类型1 DF

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

因此,这种类型派生实际上并不是您希望它做的事情——它是将族派生为
Typeable1
而不是实例。但是,很可能您需要的是内置的,因为
实例(typeable1s,typeablea)=>Typeable(sa)

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


因此,实例派生问题看起来像一个bug。关于你的答案,你引入存在主义到底是为了什么?只是为了证明你从中得到了一个功能性的
cast
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")
        []
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