Lisp 方案中的展开函数
目标:仅使用两个参数实现Lisp 方案中的展开函数,lisp,scheme,racket,Lisp,Scheme,Racket,目标:仅使用两个参数实现展开函数 参数: 第一个参数是f,它接受某个类型I的初始值并返回nil或两个元素的cons对(这两个元素中的第一个是某个类型a列表中的下一个元素,另一个是某个类型I的下一个初始值) 第二个参数是某种类型I的初始值,返回的是类型a的项列表 这就是我目前所拥有的,我不知道为什么它不起作用: (define (descending i) (if (= i 0) (list) (cons i (- i 1)))) (define nil (list))
展开
函数
参数:
- 第一个参数是f,它接受某个类型I的初始值并返回nil或两个元素的cons对(这两个元素中的第一个是某个类型a列表中的下一个元素,另一个是某个类型I的下一个初始值)李>
- 第二个参数是某种类型I的初始值,返回的是类型a的项列表
(define (descending i)
(if (= i 0)
(list)
(cons i (- i 1))))
(define nil (list))
(define (unfold f init)
(if (eq? (f init) '())
(list)
(cons init (unfold f (f init)))))
(unfold (descending 5))
应评估为
'(5 4 3 2 1)
这应该是结果,但不是。我做错了什么?首先,它应该是(5)
。然后f
将产生一对,您将使用它的两个组件
(定义(从头展开)
(如果(等式?(f init)())
(名单)
(cons(car(f init))(展开f(cdr(f init)((f init))))
但这具有可怕的计算复杂性,因为它每次迭代调用(f init)
三次。卑微的约束可以弥补这一缺陷
(define (unfold f init)
(let ((r (f init)))
(if (empty? r) ;; instead of (eq? r '())
(list)
(cons (car r) (unfold f (cdr r))))))
以及使用
和使用
我懂了!谢谢另外,如果我想定义一个返回“(-100…100)”的升序函数,我不知道为什么下面的代码停在-5:(定义(升序I)(如果(=I(-I))(列表)(cons I(+i5)))(展开升序(-100))你的条件是
(=I(-I))
,这相当于(=i0)
,所以它停在0,最后一个被消耗的是-5
。我想我只需要做(=I(105))。我只是想我可以定义这个函数,这样它就可以把所有的数字都打印到a,包括首字母的负数。(eq?whatever’())
真的是规范模式吗?或者这是一个引用@Kaz的内部笑话吗?不知道这是规范还是代码味道。我对Lisp、Scheme等的了解可以放在火柴盒中。这个问题本来也有一个标签,我就是这样发现的。我理解得足以回答这个问题,所以我尽可能多地使用OP的代码。
(define (unfold f init)
(let loop ((acc empty)
(state (f init)))
(if (empty? state)
(reverse acc)
(loop (cons (car state) acc)
(f (cdr state))))))
(define (unfold f init)
(let loop ((acc empty)
(state (f init)))
(match state
((cons x next)
(loop (cons x acc)
(f next)))
(empty
(reverse acc)))))