Vim Script で、apply と lambda
もはや誰得なのかが分からない。
関数型言語はあまり分からないんですが、こんな感じなんでしょうかねぇ。
個人的にやりたい事は出来た気はする。
[ソース]
" --------------------------------------------------------- function! s:has_apply(dict) try return has_key(a:dict, "apply") catch return 0 endtry endfunction " --------------------------------------------------------- " 関数の評価 function! s:apply(func, ...) if a:0 == 0 return s:has_apply(a:func) ? a:func.apply() : a:func() endif if a:0 == 1 return s:has_apply(a:func) ? a:func.apply(a:1) : a:func(a:1) endif if a:0 == 2 return s:has_apply(a:func) ? a:func.apply(a:1, a:2) : a:func(a:1, a:2) endif if a:0 == 3 return s:has_apply(a:func) ? a:func.apply(a:1, a:2, a:3) : a:func(a:1, a:2, a:3) endif endfunction " 無名関数の定義 function! s:lambda(lambda) let func = { "lambda" : a:lambda } function! func.apply(...) dict return eval(self.lambda) endfunction return func endfunction " --------------------------------------------------------- function! s:plus(a, b) return a:a + a:b endfunction echo s:apply(function("s:plus"), 3, 5) let minus={} function! minus.apply(a, b) dict return a:a - a:b endfunction echo s:apply(minus, 3, 5) echo s:lambda("a:1 + a:2").apply(2, 5) echo s:apply(s:lambda("a:2 - a:1"), 6, 2) echo s:apply(s:lambda("len(a:1)"), [1, 2, 3])
[出力]
8 -2 7 -4 3
apply は、可変長引数をそのまま別の関数に渡せなかったので、無理やり展開しています。
引数は3つまでしか対応していないけど、まぁしょうが無い。
lambda は、eval 関数を使用して評価しています。
a:1 や a:2 は引数の数そのままですね。
ただし、lambda 内で、ローカル変数が使えないのがちょっとネック。
使用する場合は、辞書型で渡すしかないかなー。