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)))))