2017-09-28 7 views
0

저는 학교에서 Lisp을 배우고 있는데, 만들려는 프로그램 중 하나는 mapcan을 사용하여 remove-if-not의 기능을 복제하는 프로그램 중 하나입니다. 프로그램을 만들었지 만 제대로 작동하지만 출력을 이해하지 못합니다. I 실행한다면이 프로그램이 왜 원자 목록을 반환합니까?

구체적 :

(findall 'numberp '(1 a 3)) 

를 출력한다 (1-3)

프로그램은 다음과 같다 :

(defun findAll (fct l) 
(cond 
     ((null l) nil) 
     ((mapcan (lambda(x) (if (funcall fct x) (list x) nil)) l)) 
    ) 
) 

용액 내 이해이고 다음과 같습니다 : "목록의 각 요소에 대해 l 함수를 호출합니다. 함수의 결과가 적합하고 요소 x가 true를 반환하면 요소 su를 반환합니다. 괄호로 둘러 쌓인 경우 "

특히"list (x) "에 대한 일련의 연속적인 호출이 결국 (1 2)과 같은 원자 목록을 반환하는 방법을 이해하지 못합니다.

답변

6

질문 인 SLIME (IDE)에 태그를 추가 한 이유가 확실하지 않습니다.

코드를 읽기 쉽도록 꾸미고 들여 쓰기해 보겠습니다.

(defun findAll (fct l) 
    (cond 
    ((null l) nil) 
    ((mapcan (lambda (x) 
       (if (funcall fct x) 
        (list x) 
       nil)) 
      l)))) 

그것은 그런 식으로 작성 가능하지만, 일반적으로 우리는 마지막 절은 항상라는 것을 명확하게하는 T 조건을 가지고있다. 이미 빈 목록을 다루는

(defun findAll (fct l) 
    (cond 
    ((null l) nil) 
    (t (mapcan (lambda (x) 
       (if (funcall fct x) 
        (list x) 
        nil)) 
       l)))) 

MAPCAN 때문에, 당신은 단지 COND 첫 번째 절을 삭제할 수 있습니다. findAll은 일반적으로 find-all으로 명명됩니다. 리스트 L 호출 람다 함수의 각 요소를 들어

(defun find-all (fn list) 
    (mapcan (lambda (item) 
      (if (funcall fn item) 
       (list item) 
       nil)) 
      list)) 

. 함수 착용감 요소의 결과가 참 복귀 X 경우 괄호에 둘러싸인 소자를 반환 그렇지 목록 LIST 호 람다 함수의 각 요소를 들어

nil을 반환한다. FN 함수의 결과와 ITEM 요소가 true를 반환하면 ITEM의 목록 만 반환하고, 그렇지 않으면 빈 목록을 반환합니다. 최종 결과는 람다 함수의 모든 결과 목록의 (파괴적으로) 추가 된 목록입니다.

+0

그러나 최종 결과가 함께 추가 된 이유는 무엇입니까? 그냥 목록이 아닌가요? – edoreld

+1

@edoreld : MAPCAN이 수행합니다. 해당 설명서를 참조하십시오. http://www.lispworks.com/documentation/HyperSpec/Body/f_mapc_.htm#mapcan –