Rubyã§é¢æ°åããã°ã©ãã³ã°
Rubyã§ã®å¿«é©é¢æ°åããã°ã©ãã³ã°ã©ã¤ãã追æ±ãããã¾ã, 使ããã®ã使ããªãã®ãããããããªããã®ãä½ã£ã¦ãã¾ã£ãã¨ãã話. Rubyã«ä¸æ £ããªäººãé¢æ°åããã°ã©ãã³ã°ã«ä¸æ £ããªäººã«å¯¾ãã¦é ·ãªã®ã¯ã¾ã ãããã¨ãã¦ã, C++(ã¨ãããboostã§ã®é¢æ°åããã°ã©ãã³ã°)ã«ä¸æ £ããªäººãå ¨åã§ç½®ãã¦ãã¼ãã«ãã誰å¾è¨äºã«ãªã£ã¦ãã¾ã£ã......
çµç·¯
ããããRubyã¯ã ãã¶Lispã£ã½ãã¦, ãããã¯ã¨ã¤ãã¬ã¼ã¿ã使ãã ãã§é¢æ°åããã°ã©ãã³ã°ã«ãªã£ã¦ãã¾ã. ãã¨ãã°ãããªæãã§:
%w|1 2 3 4 5|.map{|x| x.to_i}
%w|1 2 3 4 5|
ã¯'1'
ãã'5'
ã¾ã§ã®æååãããªãé
åã§, ãã®é
åã®ã¡ã½ããArray#map
*1ã«å¯¾ãã¦, åãåã£ãå¼æ°ãæ´æ°åãããããã¯ã渡ãã¦ããã¨, 1
ãã5
ã¾ã§ã®æ´æ°ãããªãé
åãå¾ããã. ãã¨ãã°é¢æ°åããã°ã©ãã³ã°è¨èªã¨ãã¦åé«ã(?)OCamlã§æ¸ããªã
List.map (fun x -> int_of_string x) [ "1"; "2"; "3"; "4"; "5" ]
ã¨ããæã. ã¡ã½ããåãã¯ãã¼ã¸ã£ã®ä½ãæ¹ãå¼æ°ã®é åºãªã©ã®è¨æ³ä¸ã®å·®ç°ãé¤ãã°ããä¼¼ã¦ãã. å®ã«é¢æ°åã£ã½ã.
æåããé¢æ°åã£ã½ãã®æ¼ãRubyã«å¯¾ãã¦å°ãæå¥ãããã¨ããã°, ãã£ãããªãã¸ã§ã¯ãæåã§ãããã®ã«, ãã¡ãã¡x
ãç¨æãã¦ããã¦x
ã«å¯¾ãã¦to_i
ãå¼ã¶ã®ãããã¦ãªãã¨ãããã¨ãããã ããã. é
åã®åè¦ç´ ã«å¯¾ãã¦to_i
ããã£ã¦è¨ã£ããã¬ã·ã¼ãã¯ãã®è¦ç´ ã«æ±ºã¾ã£ã¦ãã ã空æ°èªã, ã¿ãããª.
ã¨æããã, ããã¯å®ã¯æåããã§ãã.
%w|1 2 3 4 5|.map(&:to_i)
ã¨æ¸ãã¨æå¾ éãåã*2. ãªã«ããã¹ãã.
ãã ããã§ãã¾ã ä¸æºããã£ã¦,
%w|1 2 3 4 5|.map{|x| x.to_i * 10}
ã¿ãããªã®ãç°¡åã«æ¸ããªã. ã¹ã¤ã«to_i
ãæªãããã§ã¯ãªãã¦,
[1, 2, 3, 4, 5].map{|x| x * 10}
ã ã£ãã¨ãã¦ãç°¡åã«æ¸ããªã.
[1, 2, 3, 4, 5].map(&:*)
ã¨ããã®ã¯æ§æã¨ãã¦æ£ããã, ãã¡ãã¨*
ã¡ã½ããã®å¼ã³åºããProc
åãã¦ãããããã©, 10
ã渡ããã¨ãã§ãã¦ããªã. C++ã§ã®é¢æ°åããã°ã©ãã³ã°ã«æ
£ãã¦ãã人ãªãã°æããã¨ã ãã, boost::bindã欲ãã, ã¨. 欲ãããã°ä½ã£ã¦ãã¾ãã. ããã«æ¬²å¼µã£ã¦boost::lambdaç¸å½ã®ãã®ãä½ã£ã¦ãã¾ãã.
ã§ãããã®ã¨åºæ¬çãªä½¿ãæ¹
require 'functional/lambda' Lambda.eval do [1, 2, 3, 4, 5].map(& _1 * 10) end
ãããã¯ã§å²ãã®ããã©ããã
include Lambda::Primitive include Lambda::Variable include Lambda::Statement
ã¨ãã¦ããã¨, Lambda.eval do ... end
ã§å²ã¾ãªãã¦ã_1
çã使ããããã«ãªã. ãã®å¾ã®ä¾ã§ã¯Lambda.eval do
, end
ã¯çç¥.
_1
ã£ã¦æ¸ãã®ããã ãã
_
ã¨æ¸ãã¦ã_1
ã®æå³ã«ãªãããã«ãã¦ããã®ã§, å¼æ°ã1ã¤ãããªããªã1
ã¯æ¸ããªãæ¹ãè¦ããããã. ãã ã, _
ãæ¢ã«å®ç¾©ããã¦ããã¨ä½¿ããªã(irbãªããã§ã¯å®ç¾©ããã¦ãã¾ã£ã¦ããã£ã½ãã®ã§ä½¿ããªã).
å ·ä½ä¾
%w|1 2 3 4 5|.map(& _1.to_i * 10) # => [10, 20, 30, 40, 50]
map
ã«ãã£ã¦åè¦ç´ ã_1
ã®é¨åã«æ¸¡ã£ã¦ãã.
[1, 2, 3, 4, 5].map(& _1 * _1) # => [1, 4, 9, 16, 25]
2ä¹ãè¨ç®.
(_3 - _2 * _1).call(10, 20, 30) (_3 - _2 * _1)[10, 20, 30] # => -170
30 - 20 * 10
ãè¨ç®. (_3 - _2 * _1)
ã®é¨åã¯Proc
ãªã®ã§[]
ã§ãå¼ã³åºãã.
å¶é
å®éã®å®è£ ã¯ä»¥ä¸ã®ãããªæ¹é.
- ã¾ã
bind
ãå®ç¾© _1.method(*args)
ã¯,_1
ã®method_missing
ã®ä¸ã§:method.to_proc.bind(_1, *args)
ã«å¤æ
ãã®ãã¨ããããã«ãããããã«, ã¡ã½ããã®ã¬ã·ã¼ãã_1
ç, ãã®ã©ã¤ãã©ãªã§ç®¡çãã¦ãããªãã¸ã§ã¯ãã§ãªãã¨, bind
ãå¼ã°ããªã.
ãã¨ãã°
[1, 2, 3, 4, 5].map(& 10 * _1)
ã¯åããªã!
ããããã¨ãã®ããã«, ãã¡ãã代æ¿çãªè¨æ³ããã£ã¦,
[1, 2, 3, 4, 5].map(& :*.to_proc.bind(10, _1))
ã¨ããã°ããã. ãã ããããªãã§ãããã¯é·ãããã®ã§,
Lambda::Syntax::Method.from_symbol[] # è¨æ³ãæå¹ã«ãããã¾ããªã [1, 2, 3, 4, 5].map(& :*[10, _1])
ã¨æ¸ããããã«ãã¦ãã.
é«åº¦ãªä½¿ãæ¹ - é«éé¢æ°
é¢æ°åã¨è¨ãããã«ã¯é«éé¢æ°ã使ããã. é¢æ°ãè¿ãé¢æ°ãæ¸ããã. ã¤ã¾ãã©ã ãè¨ç®ã§è¨ãã¨ããã®
λx.λy.λz.z-y*x
ã¿ãããªã®ãæ¸ããã. ã_1
ã¨ã_2
ã£ã¦de Bruijn indexãªãã§ãã, ç°¡åããã!ãã¨åéããããã ãã©, _1
ã¯(1éã®)å¤å¼æ°é¢æ°ã®1çªç®ã®å¼æ°ã¨ããæå³ãªã®ã§de Bruijn indexã§ã¯ãªã. ã ãã
(_3 - _2 * _1)[10][20][30]
ã¨æ¸ãã¦ããã¾ããããªã.
é¢æ°ãè¿ãé¢æ°ããµãã¼ãããã«ããã£ã¦ã¯, boost::lambdaã«å£ã£ã¦protect
ã¨ããé¢æ°ãç¨æãã.
(protect(protect(_1)) - protect(_1) * _1)[10][20][30] # => -170
é¢æ°ãå¼ã³åºãããã¨ãã«protect
ãããå¤æ°ã«ã¯ä»£å
¥ãããªã代ããã«protect
ã1åå¥ãã. å¹³ããè¨ãã¨æ®µéè¨ç®ã¿ãããªãã¨ãèµ·ãã.
(protect(protect(_1)) - protect(_1) * _1)[10][20][30] # -> (protect(_1) - _1 * 10)[20][30] # -> (_1 - 20 * 10)[30] # -> (30 - 20 * 10) # -> -170
ãã , åä»ãªãã¨ã«, ãã®æ®µéè¨ç®ã®éä¸ã§ã¡ã½ããã®ã¬ã·ã¼ãããµã¤ãã®ãªãã¸ã§ã¯ãã«ãªã£ã¦ãã¾ãã¨, å¶éã®ã¨ããã§èª¬æããã®ã¨åãåé¡ãçºçãã¦ãã¾ããããªã.
(_1 - protect(_1))[10][20] # -> (10 - _1)[20] # -> TypeError!
ã§, ãµã¤ãã ã£ãã-
ã®ã¨ããã:-[...]
ã«å¤ããã°ããããã©, ãã¾ã¯æ®µéè¨ç®ãã¦ããã®ã§ããã§ããã¾ããããªã.
:-[_1, protect(_1)][10][20] # -> (_1 - protect(_1))[10][20] # -> (10 - _1)[20] # -> TypeError!
è¨ç®ã®æ®µéã1ã¤é²ãã å¾ã§:-[...]
ãããªãã¨ãããªã. ã¨ãããã¨ã¯, :-
ã«å¯¾ãã¦[...]
ãå¼ã¶ã¨ãããprotect
ããªãã¨ãããªã.
:send[protect(:-), :[], _1, protect(_1)][10][20] # -> :-.send(:[], 10, _1)[20] # -> :-[10, _1][20] # -> 10 - 20 # -> -10
ãã, ããã¯, ãªãã , ãã¢ã. ãªã«ããã, åé¡ã®å¨å¦ãããã£ãç¬éã«ãããããããæ¸ãã¦ãã¾ã£ãèªåãæãã.
ãããªé¢åãªæ®µéè¨ç®ã¹ãã«ã身ã«ã¤ããªãã¦ã, 1å¼æ°ã®é«éé¢æ°ãã使ããªããªã*3, å¤å¼æ°é¢æ°ãã«ãªã¼å*4ãã¦ãã¾ãã°ãã.
(_3 - _2 * _1).curry[10][20][30] # => -170 (_1 - _2).curry[10][20] # => -10
ããã¯ã«ã³ã¿ã³. ãããããã!
ãã®ä»æ¸ãåããªãã£ããã¨
if_
,else_
çãç¨æããbind
ãè¿ãProc
ã«ã¯ãããã¯ã渡ãã(Ruby 1.9以é)- é«éé¢æ°ã§é¢æ°ãå¼æ°ã«ã¨ãå ´å
ã¾ã¨ã
- Rubyã¯ãã¨ãã¨é¢æ°åã£ã½ã
- é¢æ°åããã°ã©ãã³ã°ãæºå«ããããã«boost::lambdaç¸å½ã®ãã®ãRubyã§å®è£
- æ¬ ç¹
- ã¬ã·ã¼ãããµã¤ãã®ãªãã¸ã§ã¯ãã ã¨ãã¾ããããªã
- é«éé¢æ°ããã©ããã
- æ¬ ç¹ãè£ãæ段
:symbol[...]
è¨æ³Proc#curry
使ã
追è¨
2011-08-20T02:29+0000 ããã¯ãã¼ã¯ã³ã¡ã³ãã¸ã®è¿ä¿¡
ãããé¢æ°åã¨è¨ãããã¨ãªããéãæ°ããã
ãé¢æ°åè¨èªãã¨ãé¢æ°åããã°ã©ãã³ã°ããæ··åãã¦ããããã«çããéåæã§ã¯ãªãã§ãããã. æä¸ã®ãé¢æ°åããã°ã©ãã³ã°ããé¢æ°åããæãã¦ããã®ã¯ããã°ã©ãã³ã°ã®ãã©ãã¤ã ã¨ãã¦ã®é¢æ°åã§ãã£ã¦, ã¨ãã«first-classãªé¢æ°ã¨immutableãªãã¼ã¿ã使ãããã°ã©ãã³ã°ææ³ãæãã¦ãã¾ã.
*1:æ¬å½ã¯Array < Enumerable#map.
*2:ã©ããã¦ããã§ãã¾ãããã®ãæ°ã«ãªã人ã¯ãã®è¾ºãèªãã: Rubyã§ã¡ã¿ããã°ã©ãã³ã° ãæé»çã«å¼ã°ããto_procã¡ã½ãã - (ï¾âï¾)o彡 sasata299's blog
*3:ããå°ãæ£ç¢ºã«è¨ãã¨ã1å¼æ°ã§ãã¤é¢æ°å ¨ä½ã®Î»æ½è±¡ãå·¦ã«å¯ã£ã¦ãããã®ãã§ããå¿ è¦ããã, ãªãã§ããã®æ¹æ³ã§ãããããã§ã¯ãªã.
*4:Ruby 1.9.2ããã¯Proc#curryãæ¨æºã§å®ç¾©ããã¦ãã. ä»åã¯Ruby 1.8ã§ã使ããããã«ç¬èªã«ãå®è£ ãã.