【问题标题】:Why can't we define closed data families?为什么我们不能定义封闭的数据族?
【发布时间】:2018-03-22 16:24:23
【问题描述】:

以下所有工作:

{-# 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)

【问题讨论】:

  • 封闭的数据族不是 GADT 吗?
  • @DavidYoung 很有趣。但我猜如果你使用 GADT,在CDF Int 中你可以找到StringDouble。对于封闭的数据系列,只有String 是可能的。
  • @ch 当然,这就是我的意思。
  • 证据在 GADT 中以另一种方式流动,并且运行时表示完全不同。

标签: haskell type-families injective-function


【解决方案1】:

(这里我只是猜测,但我想分享一下这个想法。)

假设我们可以写

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 中当前可用的更多打字机器。我不知道类型检查/推理是否可以通过这样的扩展来确定。

相比之下,type 系列不涉及值构造函数,因此不会出现此问题。

【讨论】:

  • 听起来非常可能。
  • 这确实很有意义。仍然怀疑这是否是官方原因。
  • 假设每个数据族都有一个神奇的类型族,在这里实例化为type family FamilyOf CDF a :: Nat where {FamilyOf CDF Int = 1; FamilyOf CDF Bool = 2; FamilyOf CDF = 3}。现在您可以为数据族构造函数指定类型:CDFInt :: FamilyOf CDF a ~ 1 => String -> CDF aCDFBool :: FamilyOf CDF a ~ 2 => Char -> CDF aCDFOther :: FamilyOf CDF a ~ 3 => Double -> CDF a。我不知道这是否会遇到某种麻烦,但它闻起来是正确的方向。
  • 在我上一条评论中,我的意思是“针对每个封闭的数据家族”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-28
  • 2021-03-23
  • 1970-01-01
相关资源
最近更新 更多