2016-08-19 38 views
-1

如果「應用」給定函數應用到列表中的所有元素,爲什麼下面不工作:示例應用其他比+球拍

> (apply println (list "a" "b" "c")) 
. . println: contract violation 
    expected: output-port? 
    given: "b" 
    argument position: 2nd 
    other arguments...: 
> 

兩個https://docs.racket-lang.org/reference/procedures.html給出的例子和https://docs.racket-lang.org/guide/application.html涉及到添加( +)功能。有人可以提供其他應用示例,並解釋它是如何工作的。謝謝。

回答

4

就像(apply + (list 1 2 3 4))相當於(+ 1 2 3 4),(apply println (list "a" "b" "c"))相當於(println "a" "b" "c")。但是這不是println的有效使用。如錯誤消息所示,第二個參數應該是輸出端口,而不是字符串。

要使用apply正確調用println,你必須提供一個有效的參數列表,如:

(apply println (list "a")) 
;; or 
(apply println (list "a" (current-output-port)) 

下面是使用apply與利用參數的任意數目,並且將因此總是不管工作職能的一些例子列表的長度:

(apply * (list 1 2 3 4)) ; 24 
(apply list (list 1 2 3 4)) ; (list 1 2 3 4) ¹ 
(apply set (list 1 2 3 4)) ; (set 1 2 3 4) 

¹好了,你不會真的使用applylist,因爲這只是給你回相同的列表(或者說它的副本),但你可以。

+0

你能提供申請比其他+ FN任何的例子嗎? – rnso

+0

@rnso看我的編輯。 – sepp2k

+0

我發現(apply或(list #f #f #t))不起作用。錯誤是「或:語法錯誤:或」。爲什麼? '或'也是一個像'+'這樣的函數,可以有多個參數。 – rnso

3

如果你想申請一個程序,例如。 (proc a b c)但參數在列表中提供。你可以做(proc (car l) (cadr l) (caddr l)),但你也可以做(apply proc l)。如果你在前面還有其他的參數,你甚至可以做(apply proc 5 l),它和(proc 5 (car l) (cadr l) (caddr l))一樣。 apply接受任意數量的參數,但最後需要成爲最終參數列表。

重要的是要明白,apply不是摺疊。如果您有需要且只有一個參數的程序,那麼你可以申請與一個元素,否則過程將失敗的列表..

(cons 1 2)   ; ==> (1 . 2) 
(apply cons '(1 2)) ; ==> (1 . 2) 

(cons 1 2 3)   ; ==> ERROR cons: arity mismatch 
(apply cons '(1 2 3)); ==> ERROR cons: arity mismatch 

apply是休息的說法相反:

(define (proc arg1 . argn) 
    (apply list arg1 argn)) 

(proc 1 2 3 4) ; ==> (1 2 3 4) 

這是不折疊

;; a two arity add 
(define (add a b) 
    (+ a b)) 

(apply add '(1 2))  ; ==> 3 
(apply add '(1 2 3)) ; ==> ERROR add: arity mismatch 

;; foldl is a fold 
(foldl add 0 '(1 2 3)) ; ==> 6