以下所有工作:
{-# LANGUAGE TypeFamilies #-}
type family TF a
type instance TF Int = String
type instance TF Bool = Char
data family DF a
data instance DF Int = DFInt String
data instance DF Bool = DFBool Char
type family CTF a where
CTF Int = String
CTF Bool = Char
CTF a = Double -- Overlap OK!
......但这不是(截至GHC-8.2):
data family CDF a where
CDF Int = CDFInt String
CDF Bool = CDFBool Char
CDF a = CDFOther Double
wtmpf-file24527.hs:16:19: error: parse error on input ‘where’
|
16 | data family CDF a where
| ^^^^^
是否只是没有人为实现这一点而烦恼,或者是否有一个特殊的原因导致数据系列被关闭是没有意义的?我有一个数据系列,我宁愿保持注入能力,也有机会制作一个不相交的全能实例。现在,我认为实现这项工作的唯一方法是
newtype CDF' a = CDF' (CTF a)
答案 0 :(得分:8)
(我只是猜测,但我想分享这个想法。)
假设我们可以写
data family CDF a where
CDF Int = CDFInt String
CDF Bool = CDFBool Char
CDF a = CDFOther Double
现在,这个定义引起的值构造函数的类型是什么?我很想说:
CDFInt :: String -> CDF Int
CDFBool :: Char -> CDF Bool
CDFOther :: Double -> CDF a
...但最后一个感觉非常错误,因为我们会得到
CDFOther @ Int :: Double -> CDF Int
应该被禁止,因为在关闭的数据系列中,人们会期望CDF Int
的(非底部)值必须以CDFInt
构造函数开头。
也许正确的类型
CDFOther :: (a /~ Int, a /~ Bool) => Double -> CDF a
涉及"不等式约束",但这需要更多目前在GHC中可用的打字机制。我不知道类型检查/推理是否仍然可以通过这种扩展来判定。
相比之下,类型系列不涉及值构造函数,因此不会出现此问题。