Scheme函数将一个函数应用于列表中的所有元素,无论多深,同时保留列表的结构

时间:2011-05-20 18:46:30

标签: scheme racket

嘿,我正在编写关于将一个函数应用到列表中每个元素的作业问题,并根据需要进行深入研究。

我在调用(fun(car l))时遇到错误,

mcar: expects argument of type <mutable-pair>; given 5

然而当我打电话(乐趣l)时,我得到了错误 +:将type作为第一个参数,给定:(5);其他论点是:1

   (define (map-gen fun l)
    (if (null? fun) l 
        (if (null? l) '()
            (if (list? (car l))
                (append (map-gen fun (cdr l)) (map-gen fun (car l)))
                (append (map-gen fun (cdr l)) (fun (car l)))))))

感谢任何和所有帮助!

编辑:这是在调用函数时:

(map-gen (lambda (x) (+ x 1))'(1 (2 (3 4))(((5)))))

2 个答案:

答案 0 :(得分:2)

你有向后追加的论据,我认为缺点是更好的选择。此外,检查fun是否为null是不必要的。

(define (map-gen fun l)
   (if (null? l) '()
       (if (list? (car l))
           (cons (map-gen fun (car l)) (map-gen fun (cdr l)))
           (cons (fun (car l)) (map-gen fun (cdr l))))))

另外,正如Eli在他的回答中所说,你真的应该研究cond而不是嵌套的ifs。它更加优雅,使您的代码更具可读性。

答案 1 :(得分:2)

你有一些问题:

  • fun输入应该是一个函数,因此要求(null? fun)没有多大意义,

  • 您对嵌套if的使用正是cond更优雅地解决的问题,

  • 正如Keen所说,当你以这种方式处理解构列表时,cons更合适,

  • 要求(list? (car l))被破坏 - 此时您知道l不是空列表,但如果它根本不是列表怎么办?

解决此问题的一个好方法是考虑您需要处理的l输入类型:

  • 它可以是空列表,在这种情况下答案很简单,

  • 它可以是一对(最好用pair?进行测试,但如果您不担心“不正确的列表”,list?也会有效),在这种情况下您需要使用car及其cdr执行某些操作,并以与原始结构相匹配的方式合并结果(这很容易),

  • 或者它可能是其他东西(这种情况也很容易)。

最好首先编写几个关于如何运行它的示例,然后填写代码来实现它,最后将示例转换为测试用例以验证您的解决方案是否有效。你应该真正看到HtDP - 它所谈到的“设计方法”使解决这些问题变得如此简单,以至于解决方案几乎可以自己编写。 (鉴于你在某些课程中这样做,将它指向你的老师可能是一个好主意。)