我正在使用函数mapcar
和apply
进行一些LISP练习。我处理矩阵,我必须对其行和列求和。对于第I列:
(apply #'mapcar #'+ matrix)
有效。既然我知道如何转置矩阵,我可以为行做同样的事情吗?对,那将是:
(apply #'mapcar #'+ (apply #'mapcar #'list matrix))
但我不满意 。我想直接对行进行求和,因此我对mapcar
进行了apply
:
(mapcar #'apply #'+ matrix)
没有工作,我不知道为什么。错误是
值#(FUNCTION +)不是LIST类型。 [TYPE-ERROR类型的条件]
对我来说,这将得到矩阵中的每个列表,并在每个列表中应用总和。我不能mapcar
apply
?如果不是,为什么不呢?是否有另一种方法可以仅使用mapcar
和apply
来对矩阵的行求和?
PS:我使用lispstick进行编译,矩阵是一个列表列表。实施例
((1 1 1) (2 2 2) (3 3 3))
表示3x3矩阵。
答案 0 :(得分:1)
你得到的错误来自mapcar
,它要求列表作为第一个之后的参数,而是找到函数+
。
您需要的是apply
到+
的部分应用,即
(defparameter matrix '((1 1 1) (2 2 2) (3 3 3)))
(mapcar (lambda (l) (apply #'+ l)) matrix)
==> (3 6 9)
你甚至可以为它定义一个函数:
(defun partial-application (f &rest some-args)
(lambda (&rest more-args)
(apply f (append some-args more-args))))
(funcall (partial-application #'+ 4) 5)
==> 9
(funcall (partial-application #'+ 1 2) 3 4 5)
==> 15
现在您可以使用它而不是lambda
:
(mapcar (partial-application #'apply #'+) matrix)
==> (3 6 9)
(lambda (l) (apply #'+ l))
和(partial-application #'apply #'+)
仅计算列表的总和,并且可以按照elsewhere讨论的许多不同方式进行定义。
some-args
append
: < nconc
无法安全地替换为非供应版本is not guaranteed to be fresh / LI>
醇>
允许(但不是必需)rest参数的值,以与
apply
的最后一个参数共享结构。