作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在使用带有附加类型级奇偶校验信息的自然数。 succ
已以最直接的方式成功实现:
succ :: Natural p -> Natural (Opp p)
succ = Succ
但是,我仍然在努力让 pred
进行类型检查。一个最小的例子:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
data Parity = Even | Odd
type family Opp (p :: Parity) = (r :: Parity) | r -> p where
Opp 'Odd = 'Even
Opp 'Even = 'Odd
data Natural :: Parity -> * where
Zero :: Natural 'Even
Succ :: Natural p -> Natural (Opp p)
pred :: Natural (Opp p) -> Natural p
pred (Succ n) = n
如何才能成功实现 pred
?现在我遇到了许多不同的大型且复杂的类型错误,尤其是无法推断出Opp p ~ p1
。
最佳答案
给定奇偶校验
的单例:
data SParity :: Parity -> Type where
SEven :: SParity Even
SOdd :: SParity Odd
我们可以证明Opp
的单射性
oppInj' :: Opp p ~ Opp q => SParity p -> SParity q -> p :~: q
oppInj' SEven SEven = Refl
oppInj' SOdd SOdd = Refl
现在我们可以定义:
data Natural' :: Parity -> Type where
Zero' :: Natural' Even
Succ' :: SParity p -> Natural' p -> Natural' (Opp p)
pred' :: SParity p -> Natural' (Opp p) -> Natural' p
pred' p (Succ' q n) = case oppInj' p q of Refl -> n
您可以安全地执行删除以清除所有单例垃圾:
-- for maximum symmetry, instead of relying on type applications we could
-- just substitute Proxy# in place of SParity everywhere, but meh
oppInj :: forall p q. Opp p ~ Opp q => p :~: q
oppInj = unsafeCoerce Refl -- we know this is OK because oppInj' exists
data Natural :: Parity -> Type where
Zero :: Natural Even
Succ :: Natural p -> Natural (Opp p)
pred :: forall p. Natural (Opp p) -> Natural p
pred (Succ (n :: Natural q)) = case oppInj @p @q of Refl -> n
这种模式,用单例做一些事情,然后删除它们以改善空间和时间(这里它只是一个常数因子)在 Haskell 中进行依赖类型编程时很常见。通常,您不会编写 Natural'
或 pred'
,但它们对于编写删除版本很有用。
PS:确保处理零
情况!
关于haskell - 如何通过类型级奇偶校验找到 Natural 的前身?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56924244/
我想更新一些字段的名称,有什么办法可以做到这一点,因为我们不能简单地更改它们的字段名称。 最佳答案 I want to update the name of some fields 此问题,创建的工作
我是一名优秀的程序员,十分优秀!