2016-09-24 8 views
0

지금 몇 주 동안 누적 함수를 구현하려고했습니다. 필자는 목록 전체를 반복하고 각 요소에 대해 함수를 실행하는 "Map"함수를 제대로 구현했습니다. 내가 구현하는이 기능을 사용하고스키마에서 "누적"기능 구현

(define accumulate 
    (lambda (op base func ls) 
    (if(null? ls) 
     ls 
    (cond (not (null? (cdr ls)) (op base (map func ls) (accumulate op base func (cdr ls)))) 
     (op base (map func ls) (op base (func(car ls)))) 
    ) 
    ))) 
    ;It gets to a point (the last element) after applying the map function to each element, 
    ;where it is '(number) instead of an expected "number" (outside of()). I cannot figure out 
    ;how to circumvent this. 

나는이 권리를 얻는 방법에 갇혔어요 "축적". 이 작업을 수행하는 올바른 방법은 무엇입니까?

의도 된 결과는 다음과 같습니다

당신은 목록을 작동하는 접이식 절차를 구현하려는
; accumulate: combines using OP the values of a list LS after mapping a function FUNC on it 
; (accumulate + 0 sqr '(1 2 3)) => 14 
; (accumulate * 1 sqr '(1 2 3)) => 36 
; 
+0

'cond' 문이 올바르지 않다고 생각합니다. – chepner

+0

정확히 'accumulate'의 출력이 될 것이라고 예상되는 출력을 가진 샘플 입력을 제공하십시오. –

+0

또한 왜, 어떻게해야합니까? (cond ((not (null (cdr ls)) 'map'이 필요합니까? 여러분의 입력 내용이 _lists_의 목록인지 확신 할 수 있습니까? –

답변

1

, 당신은 단순히 차례의 각 요소를 처리, map를 사용할 필요가 없습니다. 이것은 그것 같이 더 많은 것입니다 : 예를 들어

(define accumulate 
    (lambda (op base func ls) 
    (if (null? ls) 
     base 
     (op (func (car ls)) 
      (accumulate op base func (cdr ls)))))) 

:

(accumulate + 0 sqr '(1 2 3)) 
=> 14 

(accumulate * 1 sqr '(1 2 3)) 
=> 36 
+0

조언 해 주셔서 감사합니다. 참조 용 출력물 사본을 추가했습니다. –

+0

@ChristopherKelly 지금은 다릅니다! 전혀지도! –

0

당신은 구현할 수 있습니다 accumulate 재미 map,없이 이익 :

(define accumulate 
    (lambda (op base func ls) 
    (let ((z (map list ls))) ; box'em 
     (car (reverse   ; last 
     (map (lambda (x y) 
       (let ((acc (op (car x) (func (car y))))) 
       (set-car! y acc) 
       acc)) 
      (reverse (cdr (reverse  ; bulast 
          (cons (list base) z)))) 
      z)))))) 

(display (accumulate + 0 (lambda(x)(* x x)) (list 1 2 3 4))) 

; 0 1 2 3 
; 1 2 3 4 => 30 

이 에뮬레이트 (와 명백한 트위스트), r5rs Scheme에서 옛날의 느린 스트림 프로그래밍 정의

accumulate op base ls = last z 
         where 
          z = base : zipWith op z ls -- (:) is cons 

~> accumulate (+) 0 (map (^2) [1..4]) 
30 

-- 0 a b c d + 
-- 1 4 9 16 = 
-- 0 a b c d 

또한 하나의 과거의 목록 노드에 누적 결과를 "쓰는"경우 목록을 따라 이동합니다. 이것은 실제로 scanl으로 알려져 있습니다. Haskell과 그리스트에서 마지막 결과를 얻으면 foldl (왼쪽 접기)이됩니다.