努力在球拍中思考功能

Struggling to think Functionally in Racket

我的功能性思维总是有问题,这是一个典型的例子。

(define tally_table (make-hash))

(define (process-each-line)
    (define actual_percent 5)
    (define new_record (list 0))
    (define add_record (list 1))
    (define (tally-records hash_value to-be-added)
      (map (lambda (number1 number2)
        (+ number1 number2)) hash_value to-be-added))
    (if (hash-has-key? tally_table actual_percent)
      (let* ([hash_value (hash-ref tally_table actual_percent)])
        hash-set! tally_table actual_percent (tally-records hash_value add_record)
      )
      (hash-set! tally_table actual_percent new_record)
    )
)

我希望代码做的是第一次向空散列 table 添加一个新值 运行(确实如此),然后添加到散列 table连续 运行s 上的值(它没有 - 相反它 returns 列表 '(1) 和散列 table 值保持不变)。 我猜这可能与 let* 的范围有关,但我很困惑为什么 'if' 的两侧(看起来)表现不同。

您想进行函数调用,但在 if 的“then”分支中遗漏了 hash-set! 两边的括号。括号是函数调用的语法。由于您错过了它,因此它不执行函数调用。

为了与 JS 等其他语言进行比较,您不是写 f(x, y, z),而是(大致)写:

f;
x;
y;
return z;

在这种情况下,它评估hash-set!,...,(tally-records hash_value add_record),returns (tally-records hash_value add_record)的评估结果。

仅供参考,有一个函数 hash-update! 同时执行 hash-set!hash-ref,它还可以处理 hash-has-key? returns #f,也是。这意味着您根本不需要 if 表达式。你可以这样写:

(hash-update! tally-table actual-percent
              (λ (current-value) (tally-records current-value add-record))
              new-record)

已编辑:hash-update!tally-records 也将在 hash-has-key?#f 时应用。您可能需要调整 new-record 的值以保留现有行为。或者,只需使用您之前使用的常规 if