2016-09-24 6 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 

これは、リストに沿って移動するにつれて、1つの過去の現在のリストノードに累積結果を「書き込む」。これは実際にはscanlとして知られています。ハスケル、そしてそのリストからの最後の結果をとると、それはfoldl(左の倍)になります。