【问题标题】:Can Idris infer indices in types of top-level constants?Idris 可以推断顶级常量类型的索引吗?
【发布时间】:2017-10-02 15:06:16
【问题描述】:

例如,Agda 允许我这样写:

open import Data.Vec
open import Data.Nat

myVec : Vec ℕ _
myVec = 0 ∷ 1 ∷ 2 ∷ 3 ∷ []

并且myVec 将具有预期的Vec ℕ 4 类型。

但如果我在 Idris 中尝试同样的方法:

import Data.Vect

myVec : Vect _ Nat
myVec = [0, 1, 2, 3]

我从类型检查器收到一条错误消息:

 When checking right hand side of myVec with expected type
         Vect len Nat

 Type mismatch between
         Vect 4 Nat (Type of [0, 1, 2, 3])
 and
         Vect len Nat (Expected type)

 Specifically:
         Type mismatch between
                 4
         and
                 len

有没有办法在 Idris 中定义 myVec 而无需手动指定 Vect 的索引?

【问题讨论】:

  • 如果我像这样在_ 的位置添加一个洞:myVec : Vect ?len Nat; myVec = [0, 1, 2, 3],那么 Idris 能够解决这个洞?len(Emacs 中的C-c C-a)。不过,这可能不是您想要的。
  • IIRC,Idris 在类型级别将_ 视为一个全新的通用量化变量。 IE。你的表达会变成myVec : forall len. Vect len Nat

标签: type-inference agda idris


【解决方案1】:

根据 cmets,Idris 中的顶级漏洞被普遍量化,而不是通过术语推断来填补。

我相信(但最终,开发团队中的某个人将不得不确认/否认)这样做部分是为了鼓励显式类型,因此是类型导向的开发,部分是为了有一个很好的语法来表示 don't-接口实现中的关心值,例如:

Uninhabited v => Uninhabited (_, v) where
    uninhabited (_, void) = uninhabited void

下划线的这种不关心使用是从它在模式中的使用中采用的,而不是在表达式中的使用。


对于这样的事情(它不完全是你想要的,但它对常量的更改很健壮),你可以使用显式存在:

fst : DPair t _ -> t
fst (x ** _) = x

snd : (s : DPair _ p) -> p (fst s)
snd (_ ** prf) = prf

myVecEx : (n ** Vect n Nat)
myVecEx = (_ ** [0, 1, 2, 3])

myVec : Vect (fst myVecEx) Nat
myVec = snd myVecEx

fstsnd 可能在标准库中的名称不同,但我在快速搜索中没有找到。

编辑:最近一次投票再次引起了我的注意。如果您使用的是 Idris 2,我相信您可以在顶层使用 ? 而不是 _ 将其填充到我的 idris 中。 _ 在顶层,仍然是一个已删除的、隐含的、未命名的参数。 https://idris2.readthedocs.io/en/latest/implementation/overview.html#additional-type-inference

【讨论】:

  • 这一切都很好,但有没有办法(与_ 语法无关)让 Idris 推断我的索引?
  • 明确的存在主义,也许吧?或者也许使用?hole 并在您的常量固定后对其进行验证搜索?
  • (添加了一个使用存在主义的例子。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-29
  • 2021-10-17
  • 2020-02-14
  • 1970-01-01
  • 2018-01-12
相关资源
最近更新 更多