能否用mapcan或其他映射函数在Lisp中实现霍纳法则?附无映射实现代码
用Lisp高阶函数实现霍纳法则
当然可以用Lisp的高阶函数来实现霍纳法则!不过得先明确:mapcan这类映射函数其实不是最适合的——它的核心是对列表元素做映射后拼接结果,而霍纳法则本质是累积计算,所以reduce才是更贴合的选择。咱们先从你的实现说起,再看高阶函数版本。
你的递归实现
先贴出你提供的代码:
(defun Horner (lst x) (cond ((null (cdr lst)) (car lst)) (t (Horner (cons (+ (* (car lst) x) (cadr lst)) (cddr lst)) x))))
这个递归思路非常清晰:每次把列表的前两个元素按霍纳规则合并(计算 a₀*x + a₁),然后将这个结果和剩余元素组成新列表继续递归,直到只剩一个元素,就是最终的计算结果。
用reduce实现霍纳法则
reduce是Lisp里专门做累积计算的高阶函数,完美匹配霍纳法则(...((a₀*x)+a₁)*x +a₂)*x +...+aₙ的计算逻辑,实现起来非常简洁:
(defun horner-reduce (coeffs x) (reduce (lambda (acc coeff) (+ (* acc x) coeff)) coeffs :initial-value 0))
举个例子,计算多项式 3x² + 2x + 1,传入系数列表(3 2 1)和变量x,reduce的计算过程就是:((0*x + 3)*x + 2)*x + 1,完全符合霍纳法则的高效计算顺序。
关于mapcan的适用性
至于你问的mapcan,它的设计目标是生成拼接后的列表——对每个元素应用函数,然后把所有返回的列表拼接成一个新列表。而霍纳法则最终要得到的是一个单一数值,不是列表结构,所以用mapcan会非常牵强,硬要用的话得做很多不必要的转换,完全没必要。
总结
总的来说,用reduce实现霍纳法则既简洁又契合其累积计算的本质,是函数式写法的最佳选择;而mapcan这类映射函数并不适合这个场景。你原来的递归实现逻辑没问题,高阶函数版本只是换了一种更函数式的表达方式。
内容的提问来源于stack exchange,提问作者mikha koltjia
相关产品推荐
相关产品推荐

