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