2017-04-05 39 views
1

我正在使用函數mapcarapply進行一些LISP練習。我正在處理矩陣,我必須總結它的行和列。對於我有:帶有lisp的矩陣中行的總和

(apply #'mapcar #'+ matrix) 

這是行得通的。因爲我知道如何轉置一個矩陣,我可以爲行做同樣的事情嗎?沒錯,這將是:

(apply #'mapcar #'+ (apply #'mapcar #'list matrix)) 

但我不開心。我想直接總結該行,所以我做了一個applymapcar

(mapcar #'apply #'+ matrix) 

的工作,我不知道爲什麼。錯誤是

值#(FUNCTION +)不是LIST類型。 [條件類型的TYPE-ERROR]

對於我來說,這將進去矩陣中的每個列表,並在每一個應用的總和。我不能讓mapcarapply?如果不是,爲什麼不呢?是否有另一種方法來使用mapcarapply來對矩陣的行進行求和?

PS:我正在使用lispstick進行編譯,矩陣是列表的列表。示例

((1 1 1) (2 2 2) (3 3 3)) 

對於3x3矩陣。

回答

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) 

注:

  1. (lambda (l) (apply #'+ l))(partial-application #'apply #'+)僅僅計算列表的總和,並且如所討論的elsewhere可以以許多不同方式定義。

  2. append不能與非consing被安全地更換VERSON nconc因爲some-argsis not guaranteed to be fresh

靜止參數的值是允許的,但不是必需的,以與共享結構最後一個參數爲apply

+0

嗯,非常感謝。這使得很多感覺大聲笑。 – CoolTarka

+0

我感覺有人可能會像'(defun applyfun(fn)(lambda(lst)(apply fn lst))''但我不相信這個名字是正確的。 – Sylwester

+0

@Sylwester:是的,應用程序,謝謝你的建議。 – sds