应该如何理解“引理”函数的一般类型?

2024-04-27

也许这是一个愚蠢的问题。这是引用自the 哈索主义 paper https://personal.cis.strath.ac.uk/conor.mcbride/pub/hasochism.pdf:

解决这个问题的一种方法是对引理进行编码,由下式给出 参数化方程,如 Haskell 函数。一般来说,这样的引理 可以编码为类型的函数:

∀ x1 ... xn. Natty x1 → ... → Natty xn → ((l ~ r) ⇒ t) → t

我以为我明白了RankNTypes,但我无法理解这个命题的最后部分。我将其非正式地解读为“给定一个需要l ~ r,返回该术语”。我确信这种解释是错误的,因为它似乎会导致循环:我们不知道l ~ r直到证明本身得出结论,那么我怎么能期望提供一个需要这样做的术语作为证明的假设呢?

我本来期望平等证明有一个更像这样的类型:

Natty x1 → ... → Natty xn → l :~: r

非正式地说,“给定一堆Nattys,返回命题的证明l and r是相等的”(使用 GHC数据.类型.相等 https://hackage.haskell.org/package/base-4.7.0.2/docs/Data-Type-Equality.html)。这对我来说更有意义,并且似乎与您在其他依赖类型系统中所说的一致。我猜它与论文中的版本相同,但我正在努力在心理上消除这两个版本。

简而言之,我很困惑。我觉得我错过了一个关键的见解。我应该如何读取类型((l ~ r) => t) -> t?


我把它读作“给定一个需要l ~ r,返回那个 学期”

它“给定一个术语,其类型包含l,返回该术语以及所有ls 被替换为rs 在类型中”(或在另一个方向r -> l)。这是一个非常巧妙的技巧,允许您委托所有cong, trans, subst以及与 GHS 类似的内容。

这是一个例子:

{-# LANGUAGE GADTs, DataKinds, PolyKinds, TypeFamilies, TypeOperators, RankNTypes #-}

data Nat = Z | S Nat

data Natty n where
    Zy :: Natty Z
    Sy :: Natty n -> Natty (S n)

data Vec a n where
    Nil  :: Vec a Z
    Cons :: a -> Vec a n -> Vec a (S n)

type family (n :: Nat) :+ (m :: Nat) :: Nat where
    Z     :+ m = m
    (S n) :+ m = S (n :+ m)

assoc :: Natty n -> Natty m -> Natty p -> (((n :+ m) :+ p) ~ (n :+ (m :+ p)) => t) -> t
assoc  Zy     my py t = t
assoc (Sy ny) my py t = assoc ny my py t

coerce :: Natty n -> Natty m -> Natty p -> Vec a ((n :+ m) :+ p) -> Vec a (n :+ (m :+ p))
coerce ny my py xs = assoc ny my py xs

UPDATE

专业化很有启发assoc:

assoc' :: Natty n -> Natty m -> Natty p ->
            (((n :+ m) :+ p) ~ (n :+ (m :+ p)) => Vec a (n :+ (m :+ p)))
                                               -> Vec a (n :+ (m :+ p))
assoc'  Zy     my py t = t
assoc' (Sy ny) my py t = assoc ny my py t

coerce' :: Natty n -> Natty m -> Natty p -> Vec a ((n :+ m) :+ p) -> Vec a (n :+ (m :+ p))
coerce' ny my py xs = assoc' ny my py xs

丹尼尔·瓦格纳解释了评论中发生的事情:

或者,换句话说,您可以将 ((l ~ r) => t) -> t 读作“给定 假设 l ~ r 的输入良好的术语,返回相同的术语 从我们已经证明 l ~ r 并排除了这一点的背景来看 假设”。

我们来详细说明一下证明部分。

In the assoc' Zy my py t = t case n等于Zy因此我们有

((Zy :+ m) :+ p) ~ (Zy :+ (m :+ p))

这减少到

(m :+ p) ~ (m :+ p)

这显然是恒等式,因此我们可以解除该假设并返回t.

在每个递归步骤中,我们维护

((n :+ m) :+ p) ~ (n :+ (m :+ p))

方程。所以当assoc' (Sy ny) my py t = assoc ny my py t方程变为

((Sy n :+ m) :+ p) ~ (Sy n :+ (m :+ p))

这减少到

 Sy ((n :+ m) :+ p) ~ Sy (n :+ (m :+ p))

由于定义(:+)。由于构造函数是单射的

constructors_are_injective :: S n ~ S m => Vec a n -> Vec a m
constructors_are_injective xs = xs

方程变为

((n :+ m) :+ p) ~ (n :+ (m :+ p))

我们可以打电话assoc'递归地。

终于在号召下coerce'这两个术语是统一的:

 1. ((n :+ m) :+ p) ~ (n :+ (m :+ p)) => Vec a (n :+ (m :+ p))
 2.                                      Vec a ((n :+ m) :+ p)

Clearly Vec a ((n :+ m) :+ p) is Vec a (n :+ (m :+ p))假设((n :+ m) :+ p) ~ (n :+ (m :+ p)).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

应该如何理解“引理”函数的一般类型? 的相关文章

  • XMonad 在不同工作区启动

    我想在 xmonad start 上启动不同工作区中的一些应用程序 这很重要 所以 我写了以下内容startupHook startupApps String startupApps konsole emacs firefox gvim k
  • unsafeInterleaveIO 什么时候不安全?

    与其他不安全 操作不同 文档 http hackage haskell org packages archive base latest doc html System IO Unsafe html v unsafeInterleaveIO
  • 在 Haskell 中将 Maybe Int 转换为 Int

    我正在编写以下代码 并希望找到框字符串中数字的索引 所以我用了findIndex但它返回Maybe Int值 而我只想要Int value 我怎样才能转换Maybe Int to Int值或者有什么方法可以提取Int from Maybe
  • 证明后继者对等式的替代性质

    我试图理解归纳类型 精益中的定理证明 第 7 章 https leanprover github io theorem proving in lean 07 Inductive Types html 我给自己设定了一个任务 证明自然数的后继
  • 在 Haskell 中提升 State monad 中的值

    我正在 Haskell 中编写一个数独生成器 求解器作为学习练习 My solve函数接受一个UArray但返回一个State Int UArray 这样它也可以返回解决问题时发现的最大难度级别 到目前为止 这是我的功能 仍处于实验性的早期
  • Accelerate 和 Repa 是否有不同的用例?

    我一直在玩 Repa 和 Accelerate 它们都很有趣 但我不知道何时使用其中一个 何时使用另一个 他们是一起成长 是竞争对手 还是只是为了解决不同的问题 Repa 是一个用于高效数组构建和遍历的库 用 Haskell 编程并在 Ha
  • 让 GHC 生成“带进位加法 (ADC)”指令

    下面的代码将表示 192 位数字的两个未装箱字三元组添加到新的未装箱字三元组中 并且还返回任何溢出 LANGUAGE MagicHash LANGUAGE UnboxedTuples import GHC Prim plusWord2 Wo
  • 如何在 Haskell 中获得列表的中间位置?

    我刚刚开始使用 Haskel 学习函数式编程 我正在慢慢度过Erik Meijer 在 Channel 9 的讲座 http channel9 msdn com shows Going Deep Lecture Series Erik Me
  • GHC 可以为 monad 转换器派生 Functor 和 Applicative 实例吗?

    我正在尝试实施MaybeT本着mtl图书馆 使用这个非编译解决方案 LANGUAGE FlexibleInstances MultiParamTypeClasses UndecidableInstances import Control M
  • 将系统命令的结果绑定到 Haskell 中的变量

    如何在 Haskell 中运行系统命令and将其结果 即标准输出 绑定到变量 在伪 Haskell 中 我正在寻找类似以下内容的内容 import System Process main do output lt callCommand e
  • 导入 Haskell 模块

    我是哈斯克尔的新手 为什么当我尝试使用时Days from Data Time我收到此错误 Could not find module Data Time It is a member of the hidden package time
  • 如何为强制长度为 2^n 的向量类型定义可用的 Applicative 实例

    对于某些应用程序 我需要长度为 2 n 的向量 为了强制某些操作的长度匹配 我使用 ist 应用实例定义了我的类型 如下所示 LANGUAGE GADTs DataKinds FlexibleInstances FlexibleContex
  • 在 Haskell 中计算移动平均线

    我正在学习 Haskell 所以我尝试实现移动平均函数 这是我的代码 mAverage Int gt Int gt Float mAverage x a fromIntegral k fromIntegral x k lt rawAvera
  • 为什么 Haskell 的默认字符串实现是一个字符链接列表?

    Haskell 默认值的事实String众所周知 实现在速度和内存方面都效率不高 据我所知 lists一般来说 在 Haskell 中实现为单链表 并且适用于大多数小型 简单数据类型 例如Int 这似乎不是一个好主意 但是对于String这
  • 纯函数怎么能做IO呢?

    我最近了解到莫纳德随机数 http hackage haskell org package MonadRandom 0 1 13 docs Control Monad Random Class html t 3aMonadRandom图书馆
  • 将两个 Int 值相除以获得 Float 的正确方法是什么?

    我想分两份IntHaskell 中的值并获得结果Float 我尝试这样做 foo Int gt Int gt Float foo a b fromRational a b 但 GHC 版本 6 12 1 告诉我 无法将预期类型 Intege
  • Haskell 中的分类结构

    Hask通常被认为是一个范畴 其对象是类型 态射是函数 然而 我看到 Conor McBride pigworker 警告不要使用Hask多次 1 https stackoverflow com a 45905082 474311 2 ht
  • “Eta减少”并不总是在Haskell中举行?

    我发现我可以说 LANGUAGE RankNTypes f1 forall b b gt b gt forall c c gt c f1 f id f HLint 告诉我我可以在这里做 Eta 减少 但是 f2 forall b b gt
  • 如何在 Haskell 中安装库?

    我尝试使用控制 Monad Extra andM https hackage haskell org package extra 1 7 10 docs Control Monad Extra html import Control Mon
  • 使用 FoldLine 解析多个块

    对于这个简化的问题 我试图解析一个如下所示的输入 foo bar baz quux woo hoo xyzzy glulx into foo bar baz quux woo hoo xyzzy glulx 我尝试过的代码如下 import

随机推荐