æè¿ãã¹ã¿ã¼ãHaskellã§ãカリー化された関数のメリットは何か?ãã¨ãã質åãåºãããã®ããå¾ã«ãkmizuãããカリー化の誤用に対して警鐘を鳴らしてしていたãåããããã¨kmizuããã®ãã«ãªã¼åã®å®ç¾©ãã誤ç¨ã«æããã®ã§ã調ã¹ãã¨ã¨ãã«èãããã¨ã®ã¾ã¨ãã
ããããªå®ç¾©
ãã«ãªã¼åãããã¨ããç¨èªã¯ããããªãã¨ã以ä¸ã®3ã¤ã®æå³ã§ä½¿ããã¦ããããã ã
- é¨åé©ç¨ã¨ããæå³
- ããã¯æããã«ééã
- ãè¤æ°ã®å¼æ°ãåã颿°ãããä¸å¼æ°ãåã颿°ã®ãã§ã¤ã³ã«ç´ãããã¨
- ããã¯kmizuããã®å®ç¾©ãä¸éã§ããã使ãããã
- ãæ§é ä½ãä¸ã¤åã颿°ãããæ§é ä½ã®ã¡ã³ãã¼ãè¤æ°ã®å¼æ°ã«ã°ãããä¸å¼æ°ãåã颿°ã®ãã§ã¤ã³ã«ç´ãããã¨
- ããã¯åã®å®ç¾©ãã¨ããããHaskellã³ãã¥ããã£ã®å®ç¾©ã
ãé¨åé©ç¨ãã®æå³ã§ä½¿ãã®ã¯æããã«ééãã®ãªã§æé¤ãå®ç¾©2ã¨3ã«ã¤ãã¦è°è«ããããã¨ã§ãé¨åé©ç¨ã¨ã¯ä½ãã«æ»ãã
ã«ãªã¼åããã¦ãã
ãã«ãªã¼åãããã¨è¨ã£ãå ´åãå®ç¾©2ã¨3ã§ã¯æå³ãæããã«éããããªãã¡ãå ¥åããè¤æ°ã®å¼æ°ãåã颿°ããªã®ãããæ§é ä½ãä¸ã¤åã颿°ããªã®ãã¨ããç¹ãç°ãªãã
ãããããã«ãªã¼åããã¦ãããã¨è¨ã£ãå ´åãåãæå³ãæã¤ãããªãã¡ãåºåããã颿°ã¯ããä¸å¼æ°ãåã颿°ã®ãã§ã¤ã³ãã®å½¢ããã¦ããã
è¨èã§èª¬æããã¨åããã«ããã®ã§ãJavaScript ã使ã£ã¦ä¾ã示ããè¶³ãç®ã® + ã¯äºé æ¼ç®åã ããã©ãäºå¼æ°ã®é¢æ°ã ã¨ãèããããããããããä¸å¼æ°ãåã颿°ã®ãã§ã¤ã³ãã®å½¢ã«ãã¦ã¿ããã
var plus = function (x) { return function (y) { return x + y; } }
ããã¯ä»¥ä¸ã®ããã«ä½¿ãã
(plus(1))(2); â 3
ãã§ã¤ã³ã®æå³ãåããã¾ãããï¼
ãã«ãªã¼åããã¦ãããã¯ãå®å¿ãã¦ä½¿ã£ã¦ããããã ã
å®ç¾©2ã®ã«ãªã¼åãã
ä¸è¨ããã¾ãã«å®ç¾©2ã®ã«ãªã¼åã®ä¾ã ã+ ã¨ãããäºå¼æ°ã®é¢æ°ãã plus ã¨ãããä¸å¼æ°ãåã颿°ã®ãã§ã¤ã³ãã«ç´ããã®ã ããã
å®ç¾©3ã®ã«ãªã¼åãã
ãã®å®ç¾©ã§ã¯ã対象ã¨ãªã颿°ã¯å¼æ°ã¨ãã¦ä¸ã¤ã®æ§é ä½ãåããããã§ã¯ãæ§é ä½ãé åã§ä»£ç¨ãããã以ä¸ã®ãããªé¢æ°ãèããã
function plusArray(ar) { return ar[0] + ar[1]; }
ãã¡ããã以ä¸ã®ããã«åä½ããã
plusArray([1,2]); â 3
Haskell ã«ã¯ curry ã¨ãã颿°ããã£ã¦ãããã¯å®ç¾©3ã®ã«ãªã¼åããããJavaScript ã§å®è£ ãããªãããããªæãã«ãªãã
function curry(f) { return function (x) { return function (y) { return f([x,y]); } } }
使ã£ã¦ã¿ããã
var curryPlusArray = curry(plusArray);
(curryPlusArray(1))(2); â 3
ã©ã£ã¡ãæ£ããï¼
åã¯ãå®ç¾©2ã誤ç¨ãªããããªãï¼ãã¨æã£ã¦ããã®ã§ãwikipedia ã® Currying ãèªã¿ç´ãã¦ã¿ããããã¨ãå®ç¾©2ãå®ç¾©3ã®ä¸¡æ¹ã®æå³ãããã¨æ¸ãã¦ãã£ãã
In mathematics and computer science, currying is the technique of transforming a function that takes multiple arguments (or an n-tuple of arguments) in such a way that it can be called as a chain of functions each with a single argument (partial application). I
tuple ã¨ããã®ã¯ãç¡åæ§é ä½ã®æå³ã
ã¨ãã訳ã§ããã«ãªã¼åãããã¨ããå ´åã¯ãæèã«ãã£ã¦å®ç¾©2ãªã®ãå®ç¾©3ãªã®ãã夿ããªãã¨ãããªãã¨ããã®ãæ£ãããããã
å¤ãã®ããã°ã©ãã³ã°è¨èªã§ã¯ã颿°ã¯ãã«ãªã¼åããã¦ãããªãããã®ãããªè¨èªã®è©±ããã¦ããå ´åã«ãã«ãªã¼åãããã¨è¨ã£ãå ´åã¯ãå®ç¾©2ã§ããã¨è§£éãã¹ãã
Haskell ã§ã¯ããã¹ã¦ã®é¢æ°ã¯ãã«ãªã¼åããã¦ããããã¤ã¾ãã弿°ã¯ä¸ã¤ã ãã§ãå¤ã颿°ãè¿ãããã®ãããªä¸çã§ãã«ãªã¼åãããã¨è¨ã£ãå ´åã¯ãå®ç¾©3ã§ããã¨è§£éãã¹ãã
ã«ãªã¼åã®å©ç¹
ãå®ç¾©ã¯åãã£ããã©ãçµå±ã«ãªã¼åããã¨ä½ãå¬ããã®ï¼ãã¨æã人ãããã ãããã«ãªã¼åã®ã¡ãªããã¯ãé¨åé©ç¨ã§ããããã颿°ãéå½¢ã¨ãã¦ã弿°ãã«ã¹ã¿ãã¤ãºãã颿°ãä½ãåºããã以ä¸ã«ä¾ã示ãã
var plus1 = plus 1; plus1(2); â 3 var plus2 = plus 2; plus2(2); â 4
é«é颿°ã¨çµã¿åãããã¨ããã®è¡¨è¨ã®ç°¡æ½ãã¯ä¸ç®çç¶ã¨ãªãããã¨ãã°ãmap ã¨ããé«é颿°ãããã¨ããã
function map(f, ar) { var ret = []; for(var i=0; i<ar.length; i++) { ret[i] = f(ar[i]); } return ret; }
以ä¸ã¯ãmap ã« plus(1) ã¨ããé¨åé©ç¨ãã颿°ã渡ãä¾ã
map(plus(1), [1,2,3]); â[2,3,4]
plus1 ã¨ãã颿°ãç¡é§ã«å®ç¾©ããªãã¦æ¸ãã ã
ã¡ãªã¿ã« Haskell ã§ã¯ãäºé æ¼ç®åã map ãã«ãªã¼åããã¦ããã®ã§ã以ä¸ã®ãããªè¨è¿°ãå¯è½ã§ããã
map1 = map (+1)
Haskellã®é¨åé©ç¨ã¯çãå°ã¦ãªã
è¤æ°ã®å¼æ°ãåã颿°ã«å¯¾ãã¦ãããã¤ãã®å¼æ°ãåºå®ã§ãããªããããã¯é¨åé©ç¨ã¨è¨ãããScala ã«ã¯ãã®æ©è½ãããããã ã
ããããã«ãªã¼åããã颿°ã¯ãä¸å¼æ°ããåããªããé¨åãªãã¦ãªããã ãããã«ãªã¼åããã颿°ã«é¨åé©ç¨ããã¨ããã®ã¯ãçãå°ã¦ãªã表ç¾ã§ãããããããHaskell ã®åå¿è ã«ã¯ããããã風ã«èª¬æããã®åããããããããã®ã§ããã®è¡¨ç¾ãã¾ããéã£ã¦ããã