如何用letrec重写含命名let的duplicate函数?解决语法错误
如何用letrec正确重写Racket中的命名let版本duplicate函数?
你遇到的错误是因为letrec的语法缺少必要的体表达式。
命名let是语法糖:它会自动完成两步操作——定义内部递归函数,再用初始参数调用这个函数。但letrec只负责定义内部递归函数,不会自动执行调用,你必须显式写出要执行的体(也就是调用你定义的dup函数)。
正确的letrec改写版本
(define (duplicate pos lst) (letrec ((dup (lambda (i lst) (cond [(= i pos) (cons (car lst) lst)] [else (cons (car lst) (dup (+ i 1) (cdr lst)))])))) ; 显式调用dup,传入对应命名let的初始绑定参数 (dup 0 lst)))
如果要保留参数默认值的写法,也可以这样实现:
(define (duplicate pos lst) (letrec ((dup (lambda ([i 0] [lst lst]) (cond [(= i pos) (cons (car lst) lst)] [else (cons (car lst) (dup (+ i 1) (cdr lst)))])))) ; 利用默认参数,直接调用dup即可 (dup)))
验证效果
调用(duplicate 1 (list "apple" "cheese burger!" "banana"))会返回:
'("apple" "cheese burger!" "cheese burger!" "banana")
和原命名let版本的行为完全一致。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

