学习一些Scheme / Racket,所以给我一些余地。
目前尝试在不使用内置max()函数的情况下查找列表时找到最大值。
当前代码:
#lang racket
(provide max-num)
(define (max-num lst)
(define (helper lst max)
(displayln lst)
(displayln max)
(displayln " ")
(when (null? max) ; first run
(helper (cdr lst) (car lst)))
(if (null? lst)
max ; then end
(if (> (car lst) max) ; else compare
(helper (cdr lst) (car lst)) ; then update max
(helper (cdr lst) max)))) ; else keep max
(if (null? lst)
#f ; then Error
(helper lst '())) ; else run helper
)
(max-num '())
(max-num '(1 5 2 4 3))
通过DrRacket输出:
据我所知,displayln输出告诉我,我正走在正确的轨道上。但是,它最终会违反合同吗?错误而不是返回最大值。
我猜测(if(null?lst))并不想返回" max"尽管列表为空,但最后还是推向了else分支。我已经环顾四周,调试了大约一个小时,现在无济于事。任何帮助将不胜感激。
答案 0 :(得分:2)
当你这样做时,你必须知道:
(when test
do-something)
do-something-else
无论do-something-else
是否为真,它始终为test
。所发生的事情是,第一轮max
是null?
,它确实(helper (cdr lst) (car lst)))
并返回答案。然后它放弃该答案并继续if
,max
为null?
,并且(> (car lst) max)
null?
因real?
不是数字而最终失败。错误消息显示它预期为'()
,但它获得了初始值(if test1
result1
(if test2
result2
alternative2))
。
因此,除了本地定义之外,为了向你提示你应该有一个表达式。
(cond (test1 result1)
(test2 result2)
(else alternative2))
或
null?
当然,既然您知道参数不是(helper (cdr lst) (car lst))
,您只需调用when
而不是传递空列表并完全删除when
。 unless
和/src/js/libs
用于副作用,而不是用于良好的功能性方案风格。