2012-12-18 17 views
5

Próbuję nauczyć Ruby teraz po naukę Python i mam problemy z tłumaczenia tego kodu Ruby:Korzystanie z funkcji wyższego rzędu w Ruby

def compose1(f, g): 
    """Return a function h, such that h(x) = f(g(x)).""" 
    def h(x): 
     return f(g(x)) 
return h 

muszę tłumaczyć to z klocków? Czy istnieje podobna składnia w Ruby?

+2

Witamy StackOverflow. Jedna uwaga: "Przetłumacz ten kod z języka X na język Y" jest zazwyczaj niepopularna. Twoja jest trochę lepsza niż zwykle, ponieważ wygląda na to, że trochę wykopałeś i masz pojęcie, co robisz: "Czy muszę tłumaczyć to za pomocą bloków?". Mimo to mam nadzieję, że pojawi się ktoś, kto zna ruby ​​i da ci dobrą odpowiedź - nie miałbym nic przeciwko poznaniu odpowiedzi na to :-) – mgilson

+0

Jestem sam w trakcie uczenia się Pythona, więc idę aby nie wpuścić do tego rozwiązania kodu. Ale bardzo polecam ten przewodnik, próbując przetłumaczyć kod pomiędzy Python/Ruby/Perl/PHP (był bardzo przydatny dla mnie w tłumaczeniu Perl-> Python): http://hyperpolyglot.org/scripting – uptownnickbrown

+0

Och, moje złe. Zdecydowanie nie wiedziałem, że na pytania dotyczące tłumaczeń patrzy się z góry. Zastanawiam się tylko, czy w Pythonie jest podobna składnia, ponieważ wszystkie moje wyniki Google odnosiły się do bloków ... ale będę o tym pamiętać. Dzięki! – etabelet

Odpowiedz

3

Powiedzmy f i g są następujące metody:

def f(x) 
    x + 2 
end 

def g(x) 
    x + 3 
end 

Możemy zdefiniować compose1 jak:

def compose1(f,g) 
    lambda { |x| send(f, send(g, x)) } 
end 

Aby to działało, musimy zdefiniować h jak:

h = compose1(:f, :g)

Będziemy musieli przekazać nazwy metod jako ciąg/symbol do pracy send. Następnie można zrobić

h.call 3 # => 8. Więcej informacji można znaleźć here

+0

Idealny! Dziękuję Ci! – etabelet

+0

Myślę, że ta odpowiedź jest bardziej przejrzysta, ale Zach Kemp jest ładniejsza. – sunnyrjuneja

+0

Zach's jest fajny, ale pozwala na wykorzystanie istniejących metod bez wprowadzania w nich zmian, co zdecydowanie ma swoje zalety. – TheDude

6

Można to zrobić z lambdas w Ruby (używam stabby-Lambda 1.9 tutaj):

compose = ->(f,g) { 
    ->(x){ f.(g.(x)) } 
} 

Więc compose jest funkcją, która zwraca inną funkcję, jak w Twój przykład:

f = ->(x) { x + 1 } 
g = ->(x) { x * 3 } 

h = compose.(f,g) 
h.(5) #=> 16 

Zauważ, że programowanie funkcjonalne nie jest naprawdę mocną stroną Ruby - można to zrobić, ale to wygląda trochę bałagan w mojej opinii.

2

użycie lambdas

def compose1(f,g) 
    return lambda{ |x| f.call(g.call(x)) } 
end 

Exemple prowadzenia

compose1(lambda{|a| a + 1}, lambda{|b| b + 1}).call(1) 
+1

Procesy i lambdy są różnymi rzeczami (chociaż podobne). Napisałeś o procach, ale użyłeś lambdas. – skalee

+0

poprawny punkt .. Edytowany .. –

Powiązane problemy