在 Scheme 标准中是不是存在这样的过程,如果存在,它是如何调用的?
Posted
技术标签:
【中文标题】在 Scheme 标准中是不是存在这样的过程,如果存在,它是如何调用的?【英文标题】:Does such a procedure exist in a Scheme standard and if yes, how is it called?在 Scheme 标准中是否存在这样的过程,如果存在,它是如何调用的? 【发布时间】:2010-09-11 00:50:17 【问题描述】:我查找了一个过程的名称,它将过程的树形结构应用于数据的树形结构,产生结果的树形结构 - 所有三棵树都具有相同的结构。
这样的程序可能有签名:
(地图树数据函数树)
它的返回值将是 functree 的元素在相应的数据元素上逐元素应用的结果。
示例(假设过程称为map-tree):
示例 1:
(定义 *2 (lambda (x) (* 2 x))) ; *3 和 *5 的类似定义 (map-tree '(100 (10 1)) '(*2 (*3 *5)))
会产生结果
(200 (30 5))
示例 2:
(map-tree '(((aa .ab) (bb . bc)) (cc . (cd . ce))) '((汽车 cdr) cadr))
产生结果
((aa bc) cd)
但是我在查阅的 SLIB 文档中没有找到这样的功能。
这样的程序是否已经存在? 如果不是,该过程的合适名称是什么,您将如何对其参数进行排序?
【问题讨论】:
【参考方案1】:我没有一个很好的函数名称。我在下面粘贴我的实现(我称之为map-traversing
;其他人应该建议一个更好的名字)。我已经使参数顺序反映了map
本身的顺序。
(define (map-traversing func data)
(if (list? func)
(map map-traversing func data)
(func data)))
使用您的样本数据,我们有:
(map-traversing `((,car ,cdr) ,cadr) '(((aa . ab) (bb . bc)) (cc cd . ce)))
第二个示例需要 SRFI 26。(允许写入 (cut * 2 <>)
而不是 (lambda (x) (* 2 x))
。)
(map-traversing `(,(cut * 2 <>) (,(cut * 3 <>) ,(cut * 5 <>))) '(100 (10 1)))
最重要的是,与您的示例不同,您的函数必须全部不加引号。
【讨论】:
【参考方案2】:我发现使用地图遍历的以下定义,您不需要取消引用函数:
(define (map-traversing func 数据) (如果(列表?函数) (map map-traversing func 数据) (apply (eval func (interaction-environment)) (list data))))
注意:在我安装的 Guile 版本中,由于某种原因,只有 (interaction-environment) 不会引发 Unbound variable 错误。其他环境,即 (scheme-report-environment 5) 和 (null-environment 5) 会引发此错误。
注 2:随后,我在 [1] 中发现,要使 (scheme-report-environment 5) 和 (null-environment 5) 工作,您首先需要 (use-modules (ice-9 r5rs))
[1]: http://www.mail-archive.com/bug-guile@gnu.org/msg04368.html 'Re: guile -c "(scheme-report-environment 5)" ==> 错误:未绑定变量:scheme-report-environment'
【讨论】:
没错,但是你必须使用 eval,大多数 Schemers 会告诉你普通程序不应该使用 eval。 普通程序不应该使用eval
。以上是关于在 Scheme 标准中是不是存在这样的过程,如果存在,它是如何调用的?的主要内容,如果未能解决你的问题,请参考以下文章
Scheme和Clojure没有原子类型谓词 - 这是设计的吗?