【发布时间】:2020-10-22 20:25:32
【问题描述】:
我想在方案中实现一个功能堆栈。 这是我的尝试:
(define make-stack
(letrec ((do-op
(lambda (stack op . val)
(cond ((eq? op 'push)
(lambda (op . v)
(do-op (cons (car val) stack) op v)))
((eq? op 'pop)
(lambda (op . v)
(do-op (cdr stack) op v)))
((eq? op 'print)
(begin (display stack)
(newline)
(lambda (op . v)
(do-op stack op v))))))))
(lambda (op . val)
(do-op '() op val))))
堆栈可以像这个例子一样使用:
(define s make-stack)
((((((s 'push 1) 'push 2) 'push 3) 'print) 'pop) 'print)
这个例子的输出是:
((3) (2) (1))
((2) (1))
不完全是我想要的,但还不错。 我想问问这里有经验的策划者是否有办法让堆栈表现得更自然,例如这样:
(define s make-stack)
(s 'push 1)
(s 'push 2)
(s 'pop)
...
同时保持它的功能(所以没有可变性,没有set!)。
我想到的第一件事是继续返回一个不带参数的函数,但将每个 lambda (op . v) 更改为:
(lambda ()
(lambda (op . v)
...
但这不起作用,因为我们仍然需要捕获返回的函数:
> (define s make-stack)
> ((s) 'push 1)
#<procedure>
【问题讨论】:
-
您想要的语法看起来需要一个可变堆栈...
-
@Shawn 我期待一个更有经验的计划者会提出一个宏,以便通过调用堆栈然后通过捕获其输出重新定义它来实现我想要的语法。我同意这不会让人感觉很纯粹。
-
cons、car和cdr等效于push、peek和delete:-opop是peek@7、@98765433但在一个不可能的功能堆栈中,
标签: functional-programming stack scheme purely-functional