想知道是否有使用套装的替代方案!在计划/球拍。 处理作业,我们不允许使用set!
对于我的一个功能,我有一个增量器
(set! count (+ count 1))
想知道我将如何更改它以便它不会使用set!
答案 0 :(得分:1)
据推测,您不被允许使用set!
的原因是您被要求以功能性方式解决问题,而不是采取必要的方式。让我用两个不同的函数来说明,它们都决定了列表的长度:
#lang racket
(require rackunit)
(define count 0)
(define (imperative-length l)
(cond [(empty? l) count]
[else (set! count (+ 1 count))
(imperative-length (rest l))]))
(check-equal? (imperative-length '(4 3 2 1)) 4)
(define (functional-length l)
(cond [(empty? l) 0]
[else (+ 1 (functional-length (rest l)))]))
(check-equal? (functional-length '(4 3 2 1)) 4)
;; what happens if we try calling imperative-length again?
(check-equal? (imperative-length '(4 3 2 1)) 4)
;; oh no!
;; what happens if we try calling functional-length again?
(check-equal? (functional-length '(4 3 2 1)) 4)
;; yep, works fine.
这两个功能都可以正常工作,但可以重复调用功能。但!但!你可能会说,我只需要记住将计数器设置为零,或者将count
的绑定放在函数中。这是事实,但总的来说,功能解决方案并不要求程序员完全担心这种交互。
那么,这对你意味着什么?这可能意味着您需要将count
作为另一个参数传递。只是一个猜测。
答案 1 :(得分:1)
set!
。想象一下,你有这个程序:
(define (count lst)
(define num 0)
(define (helper lst)
(when (not (null? lst))
(set! num (+ num 1))
(helper (cdr lst))))
(helper lst)
num)
这几乎是Fortran的lisp语法。如何做到这一点set!
。一种方法是使用方框:
(define (count lst)
(define num (list 0))
(define (helper lst)
(when (not (null? lst))
(set-car! num (+ (car num) 1))
(helper (cdr lst))))
(helper lst)
(car num))
正如SICP视频中所述,当您引入一个突变时,您可以使用它来进行所有类型的突变。作为琐事,这是一个通常由Scheme编译器完成的转换,因此在许多情况下,实现基本语言具有set-car!
而不是set!
。怎么样没有突变呢?诀窍是遮蔽绑定:
(define (count lst)
(define (helper num lst)
(if (not (null? lst))
(helper (+ num 1) (cdr lst))
num))
(helper 0 lst))
这实际上变得更简单了。想象一下,你只需要更新一些变量,然后你就可以在其他地方使用相同的变量进行递归。