함수형 프로그래밍 2 - 커링

Posted by 大山 Sat, 24 Feb 2007 07:20:00 GMT

[참고: 이 글은 함수형 프로그래밍 1 - 함수 합성에 이어지는 시리즈임.]

앞 글에서는 두개 이상의 함수를 합성하여 새로운 함수를 만드는 방법을 살펴보았다. 이번 글에서는 함수에서 일부 인자의 값을 고정하여 새로운 함수를 만드는 커링(Currying) 기법을 다뤄본다. 우선 다음의 함수를 살펴보자.

f(x, y) = x^2 + y^2
g(y) = f(0, y) = y^2
 

위에서 함수 f는 x, y 두개의 인자를 가지는 함수이다. 함수 g는 함수 f에서 첫번째 인자의 값을 상수로 고정시켜 만든 새로운 함수이다. 이처럼 함수 f에서 일부 인자의 값을 상수로 고정시켜 새로운 함수 g를 만드는 과정을 커링이라고 부른다. (그래프로 보면, z = y^2 그래프의 모습은 z = x^2 + y^2 그래프와 x = 0 그래프가 만나는 단면의 모습이다.)

루비에서 함수 f, g는 다음과 같이 정의할 수 있다.

f = lambda {|x, y| x**2 + y**2}
g = f[0]
 

하지만 실제로 위의 코드를 실행하면, 두번째 줄에서 함수 f의 인자 개수가 틀리다는 에러가 발생하게 된다. 루비의 함수 호출은 커링 기능을 지원하지 않기 때문이다. 루비에 커링 기능을 추가하기 위해서는 다음의 코드가 필요하다. (이 코드는 Proc 클래스의 [ ] 메소드를 새롭게 정의하고 있다.)

class Proc
  def [](*a)
    if arity > a.size
      lambda {|*b| self[*(a+b)]}
    else
      self.call(*a)
    end
  end
end
 

이제 irb에서 실제로 코드를 입력해보자.

>> class Proc
>>   def [](*a)
>>     if arity > a.size
>>       lambda {|*b| self[*(a+b)]}
>>     else
?>       self.call(*a)
>>     end
>>   end
>> end
=> nil
>> f = lambda {|x, y| x**2 + y**2}
=> #<Proc:0x010abc10@(irb#1):10>
>> g = f[0]
=> #<Proc:0x010af310@(irb#1):4>
>> f[0, 5]
=> 25
>> g[5]
=> 25
 

Posted in  | Tags , ,  | 6 comments | no trackbacks