2017-03-05 3 views
0

compose関数は最後の関数を最初に適用します。つまり、送信関数を逆の順序で適用します。たとえば:合成関数の関数の使用を逆転する

((compose sqrt add1) 8) 

上記は8にADD1、その後、私は、そこで第一、第二、最初の機能を送り、適用さmycompose機能、第三などを作成したい9.

の平方根を見つけるだろう上記の例では、sqrtを最初に適用してからadd1を適用する必要があります。次のように管理することができます:

(define (mycompose L arg) 
    (let loop ((L L) 
      (res arg)) 
    (cond 
     [(empty? L) res] 
     [else (loop (rest L) ((car L) res))]))) 

(mycompose (list sqrt add1) 8) 

私は確かに良い方法があります。特に、マクロを使って上記のことを達成できますか?また、ターンごとに複数の引数を各関数ターンに送ることができますか?

+2

マクロを使わずにすべての要件を満たす '(define(mycompose。fs)(apply compose(reverse fs))'として関数を実装することができます。 –

+0

もっと良い方法があると分かりました。ありがとう。 – rnso

答えて

3

この「逆の構成」は、スラッシュと、the point-free package provides a thrush functionとよく呼ばれます。しかし、自分で実装したいとしましょう。まあ、最も簡単な方法は、thrushがちょうど逆転した引数でcomposeであることから、composeの既存の実装を再利用するために、次のようになります。

(define (thrush . fs) 
    (apply compose (reverse fs)) 

これは、実際には、ポイントフリーパッケージは、thrushを実装していますか。それでも、composeがどのように実装されているかわからないので、これはあなたにとって不満かもしれません。まあ、幸いにも、我々は簡単な倍でゼロからthrushを実装することができます

(define (thrush . fs) 
    (for/fold ([f values]) 
      ([g (in-list fs)]) 
    (λ args (call-with-values (thunk (apply f args)) g)))) 

ここでの本当のトリックは、適切に複数の値を返す関数を扱うcall-with-valuesの使用、です。 Racketのcomposeと同じように、これは複数の値を受け入れ、複数の引数としてパイプラインの後の関数に渡し、関数入力と関数出力の間に素晴らしい対称性を作り出します。

+0

明確な説明をありがとう。 – rnso