apohllo.pl
więcej niż strona domowa...
 

Operator kompozycji w Rubim

Jako język funkcyjny Haskell posiada wiele ciekawych własności, m.in. umożliwia kompozycje funkcji. Tzn. możemy zdefiniować dwie funkcje a operator kompozycji przekształca je w trzecią funkcję, która jest złożeniem tychże.

Zastanawiałem się przez chwilę, czy coś takiego możliwe jest do zrobienia w Rubim. Jak wiadomo posiada on pewne cechy języków funkcyjnych, ale nie jest tak zaawansowany jak Haskell – w szczególności jest dynamicznie typizowany, więc nie umożliwia statycznej analizy typów. Niemniej jednak możliwość zdefiniowania operatora kompozycji wydała mi się interesującym wyzwaniem.

Okazuje się, że w Rubim można zrobić to dość łatwo – wystarczy rozszerzyć definicję klasy Proc o operator powiedzmy *, który pozwalał będzie na składanie funkcji. Definicja tego operator wygląda następująco:

class Proc
  def *(other)
    ->(x){self[other[x]]}
  end
end

Dzięki tak zdefiniowanemu operatorowi możliwe jest składanie funkcji:

f = ->(x){x + 1}
g = ->(x){x * 2}
f[g[1]]            #=> 24 - zwykłe złożenie
(f * g)[1]         #=> 24 - złożenie z użyciem operatora)

Co więcej, okazuje się, że w Rubim dość łatwo można składać funkcje więcej niż 1-argumentowe (w Haskellu nie ma takiej możliwości – konieczne jest jawne użycie krotek (tuple); w praktyce sprowadza się to do składania funkcji jednoargumentowcych). Odpowiednia definicja wygląda następująco:

class Proc
  def *(other)
    ->(*args){self[*other[*args]]}
  end
end
f = ->(x,y){[x + y,x - y]}
g = ->(x,y){[x * y,x / y]}
(f * g)[10,2]               #=> [25,15]

Oczywiście w Rubim też w zasadzie budujemy krotki, ale nie zmienia to faktu, że funkcje f i g w tym przykładzie są dwuargumentowe.

Podsumowując – powyższe przykłady pokazują, że w Rubim można dość łatwo uzyskać niektóre interesujące cechy programowania funkcyjnego.

haskell | programowanie funkcyjne | ruby | Opublikowano 16:01 27-08-2012. Ostatnia modyfikacja 01:32 28-08-2012 |
comments powered by Disqus