3

以下は、スキーム内の関数のリストを指定して関数の合成を返すプロシージャを作成するために行った試みです。私は行き詰まりに達しました。私が試したものは紙の上では理にかなっていますが、どこが間違っているのかわかりません。誰かがヒントを教えてくれますか?

; (compose-all-rec fs) -> procedure 
; fs: listof procedure
; return the function composition of all functions in fs:
; if fs = (f0 f1 ... fN), the result is f0(f1(...(fN(x))...))
; implement this procedure recursively

(define compose-all-rec (lambda (fs)
     (if (empty? fs) empty
     (lambda (fs)
         (apply (first fs) (compose-all-rec (rest fs)))
     ))))

where ((compose-all-rec (list abs inc)) -2) should equal 1
4

2 に答える 2

5

別のアプローチを試してみます:

(define (compose-all-rec fs)
  (define (apply-all fs x)
    (if (empty? fs)
        x
        ((first fs) (apply-all (rest fs) x))))
  (λ (x) (apply-all fs x)))

最後に1つを返す必要があり、ヘルパープロシージャを使用して、すべての関数の実際の適用がlambda行われるのはそのラムダ(xパラメーターとリストをキャプチャする)の内部にあることに注意してください。また、より簡潔に。として表現できることに注意してください。fsapply-all(apply f x)(f x)

高次の手順が許可されている場合は、カリー化された関数foldrを返すための構文糖衣の観点から、さらに短い解を表すことができます。

(define ((compose-all-rec fs) x)
  (foldr (λ (f a) (f a)) x fs))

いずれにせよ、提案されたソリューションは期待どおりに機能します。

((compose-all-rec (list abs inc)) -2)
=> 1
于 2013-01-22T20:47:13.720 に答える
0

チェックマークを付けてください。

(define (compose-all fns)
  (assert (not (null? fns)))
  (let ((fn (car fns)))
    (if (null? (cdr fns))
        fn
        (let ((fnr (compose-all (cdr fns))))
          (lambda (x) (fn (fnr x)))))))
于 2013-01-23T14:29:36.167 に答える