partial application
Python2.5でfunctoolsというモジュールが加わったらしい。全体は眺めてないけど,関数の部分適用とかできるみたい。
>>> from functools import * >>> def foo( x, y, z ) : ... return x + y + z ... >>> add5 = partial( foo, 5 ) >>> add5( 2, 3 ) 10 >>> add10 = partial( add5, 5 ) >>> add10( 5 ) 15
そもそもOCamlだとこんなことは必要ないらしい。
- OCaml(F#)
> let foo x y z = x + y + z;; val foo : int -> int -> int -> int > let add5 = foo 5;; add5 2 3;; val add5 : (int -> int -> int) > val it : int = 10 > let add10 = add5 5;; add10 5;; val add10 : (int -> int) > val it : int = 15
Pythonのpartial関数もどきをLispで書いてみるとこんな感じ(?)でございましょうか。。。
CL-USER 1 > (defun foo (x y z) (+ x y z) ) FOO CL-USER 2 > (defun partial (fn &rest env) #'(lambda (&rest args) (apply fn (append env args))) ) PARTIAL CL-USER 3 > (let* ((add5 (partial #'foo 5)) (add10 (partial add5 5)) ) (values (funcall add5 2 3) (funcall add10 5) )) 10 15
C#だとちょっと苦しいかな。。。
- C# 3.0
public class Hoge { public void Test() { Func<int, int, int, int> fn = ( x, y, z ) => x + y + z; var add5 = fn.Partial( 5 ); Console.WriteLine( add5( 2, 3 ) ); var add10 = fn.Partial( 5, 5 ); Console.WriteLine( add10( 5 ) ); } } public static class MyExtensions { public static Func<TResult> Partial<T1, T2, T3, TResult>( this Func<T1, T2, T3, TResult> fn, T1 arg1, T2 arg2, T3 arg3 ) { return () => fn.Partial( arg1, arg2 )( arg3 ); } public static Func<T3, TResult> Partial<T1, T2, T3, TResult>( this Func<T1, T2, T3, TResult> fn, T1 arg1, T2 arg2 ) { return ( x ) => fn.Partial( arg1 )( arg2, x ); } public static Func<T2, T3, TResult> Partial<T1, T2, T3, TResult>( this Func<T1, T2, T3, TResult> fn, T1 arg1 ) { return ( x, y ) => fn( arg1, x, y ); } }
こんな風に全部に対して書いていかなきゃならないかな?苦笑
何か別のエレガントな方法があるでしょうか。。。