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

Racket契约违反错误排查及firsts函数实现优化咨询

firsts函数的实现问题与解决方案

问题梳理

你需要实现的firsts函数,接收的参数要么是空列表,要么是仅包含非空列表的列表,返回由每个内部列表的第一个S-expression组成的列表。但当前代码调用(first '(()))时触发合约错误:Contract violation, (and/c list? (not/c empty?)) expected given: '(),核心问题如下:

现有代码的问题

  • 命名冲突:Racket内置了first函数,它要求参数必须是非空列表,你自定义的函数和内置函数重名,容易引发调用混淆,这也是触发合约错误的直接原因之一。
  • 逻辑分支缺失:你的cond仅处理了输入列表为空、输入列表首元素为空这两种情况,完全没覆盖输入列表首元素是非空列表的核心场景,不符合你设定的输入前提。
  • 输入违反约定:你调用(first '(()))时,传入的列表包含空内部列表,这和你“输入仅包含非空列表”的设定矛盾,进一步触发了内置函数的合约检查。

正确实现方案

严格符合输入约定的实现

改名函数避免冲突,只处理合法输入:

(define (firsts lst)
  (cond
    [(null? lst) '()]
    [else (cons (car (car lst)) (firsts (cdr lst)))]))

测试效果:

  • (firsts '()) → '()
  • (firsts '((a b) (c d) (e f))) → '(a c e)

兼容含空内部列表的实现

如果需要兼容输入包含空列表的情况(偏离原需求),可以补充分支:

(define (firsts lst)
  (cond
    [(null? lst) '()]
    [(null? (car lst)) (cons '() (firsts (cdr lst)))]
    [else (cons (car (car lst)) (firsts (cdr lst)))]))

此时调用(firsts '(() (a b)))会返回'(() a),不会触发错误。

规范与最优实践

  • 函数命名要避开内置函数,用firsts这类语义明确的名称,避免混淆。
  • 递归实现必须覆盖所有可能的输入场景,基线情况(空列表)和递归逻辑清晰分离。
  • 若输入严格符合“仅含非空列表”的约定,第一种实现更简洁高效,无需额外分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:02:49