Dan*_* P. 3 lisp scheme racket
目标:unfold仅使用两个参数实现函数.
论点:
这是我到目前为止,我不知道为什么它不起作用:
(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))
Run Code Online (Sandbox Code Playgroud)
应该评估
'(5 4 3 2 1)
Run Code Online (Sandbox Code Playgroud)
这应该是结果,但事实并非如此.我究竟做错了什么?
首先,它应该是(unfold descending 5).然后f会产生一对,你会使用它的两个组成部分,
(define (unfold f init)
(if (eq? (f init) '())
(list)
(cons (car (f init)) (unfold f (cdr (f init))))))
Run Code Online (Sandbox Code Playgroud)
但这具有可怕的计算复杂性,因为它(f init)每次迭代调用三次.谦虚的let约束力可以解决这个问题.
(define (unfold f init)
(let ((r (f init)))
(if (empty? r) ;; instead of (eq? r '())
(list)
(cons (car r) (unfold f (cdr r))))))
Run Code Online (Sandbox Code Playgroud)
(define (unfold f init)
(let loop ((acc empty)
(state (f init)))
(if (empty? state)
(reverse acc)
(loop (cons (car state) acc)
(f (cdr state))))))
Run Code Online (Sandbox Code Playgroud)
并使用match.
(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)))))
Run Code Online (Sandbox Code Playgroud)