You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Idris2中Parity示例编译报错:j在此上下文不可访问问题求助

问题分析与修复

错误原因

Idris 2 0.7.0对with块的作用域处理逻辑和Idris 1有显著差异:Idris 1会自动将with匹配过程中产生的绑定变量(比如示例中的j)暴露给分支的模式匹配上下文,但Idris 2对作用域做了更严格的限制,不会自动提升这类变量,导致你在分支模式中引用j时出现“不可访问”的错误。这和multiplicity无关,核心是作用域规则的变化。

修复方案

假设你的原始代码类似以下结构:

data Parity : Nat -> Type where
  Even : Parity (n + n)
  Odd  : Parity (S (n + n))

helpEven : (j : Nat) -> Parity j -> Parity (S j)
helpEven j Even = Odd {n = S j}
helpEven j Odd  = Even {n = j}

helpOdd : (j : Nat) -> Parity j -> Parity (S j)
helpOdd j Even = Odd {n = j}
helpOdd j Odd  = Even {n = S j}

parity : (n : Nat) -> Parity n
parity Z = Even {n=Z}
parity (S k) with (parity k)
  parity (S (j + j))     | Even = Odd {n=j}
  parity (S (S (j + j))) | Odd  = Even {n=S j}

可以通过直接从Parity构造函数中提取绑定变量来修复,不需要在分支的左侧模式中展开k的结构:

parity : (n : Nat) -> Parity n
parity Z = Even {n=Z}
parity (S k) with (parity k)
  parity (S k) | Even {n=j} = Odd {n=j}
  parity (S k) | Odd {n=j}  = Even {n=S j}

原理说明

修改后,我们直接从Even/Odd构造函数的命名参数中获取j,而不是依赖with块自动传递模式匹配产生的变量。Idris 2会自动推导k和j的关系(比如k = j + j对应Even分支),完全满足类型检查要求,同时避免了作用域问题。

如果需要保留左侧的模式匹配写法,也可以通过proof参数显式捕获with块的上下文,但这种写法更繁琐:

parity : (n : Nat) -> Parity n
parity Z = Even
parity (S k) with (parity k) proof p
  parity (S k) | Even = case k of
    j + j => Odd {n=j}
  parity (S k) | Odd = case k of
    S (j + j) => Even {n=S j}

内容的提问来源于stack exchange,提问作者Johnny Liao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:53:12