Types 为什么《如何设计程序》一书在答案表上选择了这种方法?
我正在使用著名的书《如何设计程序》。更具体地说,是第一版(我有实物版) 在第六章中,有一些结构练习。在其中一种情况下,您需要模拟交通信号灯并使用效果(突变)来更改它们 我指的是练习6.2.5中关于功能Types 为什么《如何设计程序》一书在答案表上选择了这种方法?,types,scheme,racket,recipe,htdp,Types,Scheme,Racket,Recipe,Htdp,我正在使用著名的书《如何设计程序》。更具体地说,是第一版(我有实物版) 在第六章中,有一些结构练习。在其中一种情况下,您需要模拟交通信号灯并使用效果(突变)来更改它们 我指的是练习6.2.5中关于功能next的练习,该练习假定为您提供交通灯的下一种颜色 本书提供的答题纸为: (start 50 160) (draw-solid-disk (make-posn 25 30) 20 'red) (draw-circle (make-posn 25 80) 20 'yellow) (draw-circ
next
的练习,该练习假定为您提供交通灯的下一种颜色
本书提供的答题纸为:
(start 50 160)
(draw-solid-disk (make-posn 25 30) 20 'red)
(draw-circle (make-posn 25 80) 20 'yellow)
(draw-circle (make-posn 25 130) 20 'green)
; -------------------------------------------------------------------------
;; clear-bulb : symbol -> true
;; to clear one of the traffic bulbs
(define (clear-bulb color)
(cond
[(symbol=? color 'red)
(and (clear-solid-disk (make-posn 25 30) 20)
(draw-circle (make-posn 25 30) 20 'red))]
[(symbol=? color 'yellow)
(and (clear-solid-disk (make-posn 25 80) 20)
(draw-circle (make-posn 25 80) 20 'yellow))]
[(symbol=? color 'green)
(and (clear-solid-disk (make-posn 25 130) 20)
(draw-circle (make-posn 25 130) 20 'green))]))
;; tests
(clear-bulb 'red)
; -------------------------------------------------------------------------
;; draw-bulb : symbol -> true
;; to draw a bulb on the traffic light
(define (draw-bulb color)
(cond
[(symbol=? color 'red)
(draw-solid-disk (make-posn 25 30) 20 'red)]
[(symbol=? color 'yellow)
(draw-solid-disk (make-posn 25 80) 20 'yellow)]
[(symbol=? color 'green)
(draw-solid-disk (make-posn 25 130) 20 'green)]))
;; tests
(draw-bulb 'green)
; -------------------------------------------------------------------------
;; switch : symbol symbol -> true
;; to switch the traffic light from one color to the next
(define (switch from to)
(and (clear-bulb from)
(draw-bulb to)))
;; tests
(switch 'green 'yellow)
(switch 'yellow 'red)
; -------------------------------------------------------------------------
;; next : symbol -> symbol
;; to switch a traffic light's current color and to return the next one
(define (next current-color)
(cond
[(and (symbol=? current-color 'red) (switch 'red 'green))
'green]
[(and (symbol=? current-color 'yellow) (switch 'yellow 'red))
'red]
[(and (symbol=? current-color 'green) (switch 'green 'yellow))
'yellow]))
(next 'red)
(next 'green)
(next 'yellow)
(next 'red)
在下一个函数中,我做了类似的事情,在提供的测试中获得了相同的结果:
(define (next current-color)
(cond
[(symbol=? current-color 'red) (switch 'red 'green)]
[(symbol=? current-color 'yellow) (switch 'yellow 'red)]
[(symbol=? current-color 'green) (switch 'green 'yellow)]))
与本书的答案不同,我的代码不使用和,也不使用任何符号(例如“红色”)
这种差异引起了我的兴趣,因为这本书非常强调教你如何设计代码。我感兴趣的一点是,最初的解决方案使用and(结合后续效果),这似乎是不必要的,除了在每个条件语句末尾使用“孤独”的“红色”、“黄色”或“绿色”
我不明白最后一个symbol语句或and的目的
是否有某种风格或概念上的原因使这种方法看起来更冗长、更不清晰
我读这本书正是为了改进我编写代码的方式。Racket,作为一种方案,是一种新的方法。这意味着复合表达式中的最后一个表达式是整个表达式的值
这包括一个带引号的符号。它的值,即符号,是返回的值
函数调用(下一个当前颜色)
切换交通灯的颜色并返回指示交通灯新颜色的符号:
;; next : symbol -> symbol
您的代码切换颜色并返回true
(根据开关的规范)
:
这将改变功能next
的使用方式。有了这本书的设计,我们就可以写作了
....
(let loop ( ... )
.....
(let ((current-color (next current-color)))
......
))
....
在您的设计中,这种自然风格的循环代码是不可能的
一般性说明:这些规范称为类型,我们让类型指导我们在代码中使用函数。它们帮助我们看到什么进入,什么流出,这样我们就可以连接匹配的电线了。太好了。当我问的时候,这对我来说是看不见的。这完全有道理。您所说的在使用递归函数时将特别有用。谢谢。很高兴能帮上忙。这些规范称为类型BTW,我们让类型指导我们在代码中使用函数。它们帮助我们看到什么进入,什么流出,这样我们可以连接匹配的电线快乐小径,是的。我过去只在使用静态类型语言(如标准ML)时才担心类型。因为Racket是动态类型的,所以我并没有真正注意到。但答题纸使用注释来表示I/O类型是有原因的。我将开始使用功能前注释作为一种良好的实践。使用和来排序副作用是一个缺陷,第二版通过更改为功能更强大、更灵活的“universe”教学包来修复该缺陷。这是一个更干净的设计,我建议至少看看第二版,看看它是如何做到的。
....
(let loop ( ... )
.....
(let ((current-color (next current-color)))
......
))
....