球拍合同违规(最大递归功能)

时间:2018-06-07 23:22:18

标签: scheme max racket contract

学习一些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输出:

enter image description here

据我所知,displayln输出告诉我,我正走在正确的轨道上。但是,它最终会违反合同吗?错误而不是返回最大值。

我猜测(if(null?lst))并不想返回" max"尽管列表为空,但最后还是推向了else分支。我已经环顾四周,调试了大约一个小时,现在无济于事。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

当你这样做时,你必须知道:

(when test
  do-something)
do-something-else

无论do-something-else是否为真,它始终为test。所发生的事情是,第一轮maxnull?,它确实(helper (cdr lst) (car lst)))并返回答案。然后它放弃该答案并继续ifmaxnull?,并且(> (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而不是传递空列表并完全删除whenunless/src/js/libs用于副作用,而不是用于良好的功能性方案风格。