Currying w Rubim
W nawiązaniu do wcześniejszego wpisu na temat możliwości zaimplementowania operatora kompozycji w Rubim w tym wpisie pokazuję, że Ruby posiada jeszcze jedną cechę języków funkcyjnych. Mianowicie umożliwia wywoływanie funkcji z niepełną listą parametrów. W terminologii programowania funkcyjnego nazywane jest to curryingiem. Zasadnicza idea polega na tym, że skoro funkcje traktujemy funkcje jako pierwszorzędnych obywateli w danym języku, to powinniśmy mieć możliwość częściowej aplikacji tych funkcji do ich argumentów – tzn. jeśli liczba argumentów jest mniejsza niż wymagana, otrzymujemy nową funkcję, która dopiero po dostarczeniu brakujących argumentów zwróci konkretną wartość.
W chwili gdy poznałem tę funkcję Haskella, uświadomiłem sobie, że w Rubim nie mamy takiej możliwości, tzn.
plus = ->(x,y) { x + y } plus_two = plus[2] # ArgumentError: wrong number of arguments (1 for 2)
Okazuje się jednak, że klasa Proc definiuje wywołanie curry
, które realizuje tę funkcjonalność.
Zatem korzystając z tego wywołanie możemy osiągnąć pożądany efekt:
plus = ->(x,y) { x + y } plus_two = plus.curry[2] plus_two[3] # => 5 plut_two[5] # => 7
Co więcej – uzyskana w ten sposób funkcja nie wymaga wywoływania curry
w celu częściowej aplikacji argumentów:
multiply = ->(x,y,z) { x * y * z } multiply_2 = multiply.curry[2] multiply_2_3 = multiply_2[3] multiply_2_3[5] #=> 30