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

如何在DrRacket中借助Simply Scheme扩展实现句子处理

解决Scheme句子处理的类型转换、扩展获取与功能实现问题

咱们一步步拆解你遇到的问题,逐个解决:

1. 先理清类型错误与相等判断的核心问题

你输入的'(h)是一个符号列表(在DrRacket的SICP语言里显示为(mcons 'h '())),而你用的symbol->string、list->string这些函数都有明确的参数要求,直接用列表肯定会报错:

  • symbol->string需要单个符号(比如'h),不是列表,你得先取列表的第一个元素:(symbol->string (car '(h))),这样就能得到字符串"h"。
  • list->string要求列表元素是字符(比如'(#\h)),不是符号,所以用'(h)会触发类型违规。
  • 关于相等判断:
    • eq?判断的是两个对象是否是同一个内存引用,所以'(h)和'(h)在SICP语言里是不同的cons单元,返回#f,你应该用equal?来判断内容相等:(equal? '(h) '(h))会返回#t。
    • 要判断符号'h和字符串"h"是否相等,得先把符号转成字符串:(equal? (symbol->string 'h) "h"),结果是#t。

2. 获取《Simply Scheme》的扩展函数

DrRacket直接支持《Simply Scheme》的扩展,两种简单方式:

  • 直接切换语言:打开DrRacket后,点击顶部"Language"菜单,选择"Choose Language...",搜索并选中"Simply Scheme",确认后就能直接用书中的sentence、word、keep、last等函数。
  • 通过包导入:如果找不到语言选项,打开"File"菜单的"Package Manager...",搜索simply-scheme安装。安装完成后,在代码开头加(require simply-scheme),就能调用所有扩展函数了。

3. 实现ends-e句子处理功能

方式一:用《Simply Scheme》扩展(最简洁)

完全贴合你需求的写法,利用书中的封装函数:

(define (ends-e sent)
  ; keep函数筛选句子中符合条件的单词
  (keep (lambda (wd)
          ; last取单词最后一个字符,判断是否为'e'
          (equal? (last wd) 'e))
        sent))

测试效果:

> (ends-e '(only the good die young))
'(the die)

方式二:标准Scheme自行实现

如果想在SICP等标准Scheme环境里写,核心是把符号转成字符串处理字符,再筛选:

(define (ends-e sent)
  ; filter函数筛选列表元素
  (filter (lambda (wd)
            (let ((word-str (symbol->string wd)))
              ; 取字符串最后一个字符,判断是否为字符类型的#\e
              (equal? (string-ref word-str (- (string-length word-str) 1)) #\e)))
          sent))

测试同样能得到预期结果:

> (ends-e '(only the good die young))
'(the die)

总结

  • 标准Scheme里没有"sentence"类型,你说的句子本质是符号列表,每个符号对应一个单词,处理时要在符号、字符串、字符之间做转换。
  • 《Simply Scheme》的扩展能大幅简化句子和单词的处理逻辑,DrRacket里获取这些扩展非常方便。
  • 相等判断要选对函数:eq?判断同一对象,equal?判断内容相等,跨类型比较时记得先做类型转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:05:22