2009-07-26 7 views
1

この例では、composeメソッドとhydrateメソッドの両方でlambdaが使用されています。ラムダはここで何をしていますか?この例のラムダの目的は何ですか?

def compose *lambdas 
    if lambdas.empty? 
    lambda { nil } 
    elsif lambdas.size == 1 
    lambdas.first 
    else 
    lambda do |n| 
     lambdas.first.call(compose(*lambdas[1..-1]).call(n)) 
    end 
    end 
end 

def hydrate(modulus, printable_form) 
    i = 0 
    lambda do |n| 
    (i = (i + 1) % modulus) == 0 && printable_form || n 
    end 
end 

print(((1..100).map 
    &compose(
    hydrate(15, 'Watermelon'), 
    hydrate(5, 'Melon'), 
    hydrate(3, 'Water'))).join(' ')) 

私の2番目の質問は、 - 単語composeの前にアンパサンドが必要なのは何ですか?

答えて

8

関数composeは関数のリストを取り、リスト上のすべての関数の構成である新しく割り当てられた関数を返します。空リストをむしろ奇妙に扱うよう書かれています。最初のケースを無視する必要があるかもしれません。 (通常は恒等関数を作成すべき機能の空のリストを構成するが、それはあなたの例が何をするのか。私は基本ケースとして

lambda do |n| { n } 

を期待しているだろうではありません。)

それはでlambdaを使用する必要があります新しい関数を作成するlambdaは、nが残りの関数の構成を呼び出す結果を返したときに新しい関数を作成し、最後に最初の関数を適用するという新しい関数を作成します。 のように、これは良いコードではありません。関数リストの再帰は、構成がと呼ばれるたびに繰り返されます。例では:

  • 関数の合成を作成する機能の構成を適用すると、コードが正しく書かれていたのに対し場合は線形時間と空間

がかかり

  • 一定の時間と空間を使用しています

    • functio コスト線形時間と(ゼロスペース)何の割り当てを必要としないはず

    は、残念ながら私がするのに十分なルビーを知らないべき機能の組成物を適用するNS べきコスト線形時間と空間

  • composeの例を書いてください。しかし他の人はそうするでしょう。

  • 5

    2番目の質問は、&の処理を尋ねます。

    The unary ampersand in Rubyを見ると、アンパサンドはprocをブロックに変換します。

    例:

    irb(main):001:0> def meth1 
    irb(main):002:1> yield "Hello" 
    irb(main):003:1> end 
    => nil 
    

    はブロックとmeth1を呼び出すと、期待通りに動作します:

    irb(main):004:0> meth1 { |s| puts s } # Calling meth1 with a block 
    Hello 
    => nil 
    

    PROCを呼び出すと、動作しません:

    irb(main):005:0> p = Proc.new { |s| puts "In proc: #{s}" } 
    => #<Proc:[email protected](irb):5> 
    irb(main):006:0> meth1 p 
    ArgumentError: wrong number of arguments (1 for 0) 
         from (irb):6 
         from C:/Ruby19/bin/irb:12:in `<main>' 
    

    しかし、それは動作しない場合Procをブロックに変換します。

    irb(main):007:0> meth1 &p # Convert the proc to a block 
    In proc: Hello 
    => nil 
    

    これは、次のコードを使用するときに起こっているのと同じことである。ここでは

    irb(main):001:0> def meth2(&block) # Block is converted to Proc 
    irb(main):002:1> puts block.class.to_s if block_given? 
    irb(main):003:1> end 
    => nil 
    irb(main):004:0> meth2 { puts "Hi There" } 
    Proc 
    => nil 
    irb(main):005:0> 
    

    は、ブロック間の違いについて別の記事、block vs lambda vs procです。

    6

    この正確なコードがどこにあるのかは分かりませんが、Reginald Braithwaiteのブログのコードを少し軽く変更したようです。 (コードは、より一般的にはRubyと関数型プログラミングにおける関数型プログラミングの深刻な議論に使用FizzBu​​zz質問に対して意図的にオーバーザトップ溶液であった。)ここ

    は、元のポストである。

    +0

    よく覚えている:-) – mikej

    関連する問題