é¢æ°ã®å帰çãªå®ç¾©ã«ååä»ãã¯å¿ è¦ã
çµè«ããè¨ãã¨, ååãä»ãããã¨ãªãå帰çãªé¢æ°ãå®ç¾©ãããã¨ã¯å¯è½. ç¹å®ã®ããã°ã©ãã³ã°è¨èªã§ã©ããã¨ããããã¯æ½è±¡æ¦å¿µã¨ãã¦ã®é¢æ°ã®å帰ãååãªãã«å®ç¾å¯è½ãã©ããã¨ãã話(ååãªãã«å®ç¾ã§ããããã°ã©ãã³ã°è¨èªã¯åå¨ãããã¨ãã話).
çºç«¯
id:naoyaããããããããã¤ã¼ãããã¦ãã.
å帰ãæ¸ãã¨ãã«ä½æ°ãªãé¢æ°ã«ååã¤ããã let ã§æç¸ããããã¦ããã©ãå帰ã«ã¯ä¸é é¢ä¿ãå¿ è¦ã§ãããã®å®ç¾ã«ã¯è¨å·ãæ¬è³ªçã«é¢ãããã¨ãããååã¥ãã®è¡çºãå¿ ç¶ã ã£ããã¨ãåãã£ããããã°ã©ãã³ã°ããã¨ãã®è¦ç¹ãå¤ãããª
— naoya (@naoya_ito) 2022å¹´8æ12æ¥
ãã¨ãã°ä»¥ä¸ã®ããã«æ¸ããã¨ãã®let fact =
ã¿ãããªè©±.
let fact = n => n <= 1 ? 1 : n * fact(n-1)
ã¡ãªã¿ã«, 話ã¯ä¸è¦é¸ãããã©, ããæ¸ããã¨å¿
ç¶çã«åãã¹ã³ã¼ãå
ã®åä¸å¤æ°åã®åå®ç¾©ã§ä¸ã¤åã®å®ç¾©ãåç
§ã§ããªããã¨ãæå³ãã(ããããããåä¸ã¹ã³ã¼ãã§ã®åå®ç¾©ãç¦æ¢ãã¦ãããã¨ãå¤ã). éã«, ã§ããããã«ãã¦ããè¨èªããã£ã¦, ãã¨ãã°OCamlã§ã¯å帰çãªå®ç¾©ãããã¨ãã¯let rec é¢æ°å å¤æ°å =
ã¨æ¸ããªããã°ãªããªããã, ãµã¤ãã®let
~in
ã§ã¯åãå¤æ°åã»é¢æ°åãé£ç¶ã§ä½¿ã£ã¦ãã(å³è¾ºã«ãã®å¤æ°åãæ¸ãããä¸ã¤åã®å®ç¾©ãåç
§ããããã以éã¯å¤ãæ¹ã®å®ç¾©ã¯shadowããã). Scalaã®for
ãå帰çãªå®ç¾©ãæ¸ããã¨ã¯ãªãã®ã§åãååã§å¤ãå¤ãåç
§ã§ããããã«ãªã£ã¦ãã.
(* OCaml *) let x = 5 in let x = x * x in x (* => 25 *)
// Scala for { x <- Some(5) x <- Some(x * x) } println(x) // => 25
è¨ããããã¨ã¨ãã¦ã¯, ãååãã¤ãããããã ãã§ãªããä»ã¤ãããã¨ãã¦ãããã®ååã, åä»ãããã対象ã®ä¸ã§ä½¿ãããã¨ãæ示çã«è¨±ãã¦ããªãã¨(ååã«ãã)å帰çãªå®ç¾©ã¯å¯è½ã«ãªããªã*1.
èªå·±è¨åããããã®ããªããã£ã
ãã¨ãã°, JavaScriptã«ã¯arguments.callee
ã¨ããããªããã£ãããã, ããã使ãã¨å帰å¼ã³åºããã§ãã. ããã使ã£ã¦ä»¥ä¸ã®ããã«éä¹ãæ±ããç¡åé¢æ°ãæ¸ãã(strict modeã§ã¯ãã¡ã ãã©).
(function(n) { return n <= 1 ? 1 : n * arguments.callee(n-1) })
ä»ã®è¨èªã§ãä¼¼ããããªãã®ã¯ãããããããã®ã®, å¥ã®ã¡ã¸ã£ã¼ãªæ¹æ³ã¨ãã¦ã¯, ãªãã¸ã§ã¯ãæåè¨èªã®this
ãæ¬è³ªçã«ã¯å帰çãªå¦çãå®ç¾ããæ¹æ³ã¨è¨ãã(èªå·±è¨åã ãã). ãã¨ãã°Scalaã§ã¯ä»¥ä¸ã®ããã«this
ã使ã£ã¦éä¹ãæ±ããç¡åé¢æ°ãæ¸ãã.
new Function1[Int,Int] { def apply(n: Int): Int = if n <= 1 then 1 else n * this(n-1) }
ã¨ã¯ãã, arguments.callee
ãthis
(ããã³apply
)ã¨ãã£ãç¹å¥ãªååã使ã£ã¦ãã¦, ãªãã ãããã¯ãããæãããã.
ä¸åç¹ã³ã³ããã¼ã¿ã«ããç¡åå帰
è¨èªæ©è½ã¨ãã¦ã¯é¢æ°ã®ã¿ã使ã, ç¹å¥ãªããªããã£ããªãã«é¢æ°ã®å帰ãæ¸ããªããã®ã. ãªãã¨, æ¸ãã. ä¸åç¹ã³ã³ããã¼ã¿ã¨ãããã®ã(ç¡æ°ã«)ãã£ã¦, ããã使ãã¨æ¸ãã. ä¸åç¹ã³ã³ããã¼ã¿ã®å ·ä½ä¾ã¯, ãã¨ãã°Yã³ã³ããã¼ã¿ãZã³ã³ããã¼ã¿ãæåã§, Zã³ã³ããã¼ã¿ãJavaScriptã§æ¸ãã¨ä»¥ä¸ã®ããã«ãªã.
let Z = f => (x => f(y => x(x)(y)))(x => f(y => x(x)(y)))
ããã使ãã¨éä¹ãè¨ç®ããé¢æ°ã¯ä»¥ä¸ã®ããã«æ¸ãã.
Z(f => (n => n <= 1 ? 1 : n * f(n-1)))
Z(f => (n => n <= 1 ? 1 : n * f(n-1)))(5)
// => 120
ãZ
ã£ã¦ååã¤ãã¨ãããªãããã£ã¦? ã§ã¯ããæ¸ãã.
(f => (x => f(y => x(x)(y)))(x => f(y => x(x)(y))))(f => (n => n <= 1 ? 1 : n * f(n-1)))
ã¾ãããã®é¢æ°ã¯å帰çã«ãªã£ã¦ã¾ããã¨è¨ããã¦ããã»ãã¾ã?ãã£ã¦æã£ã¦ãã¾ããã©, ãªã£ã¦ã. ç¡åå帰ã§ãã. ããããã, å¼æ°ã«ååã¤ãã¾ãã£ã¨ãããªãããã£ã¦? ã¾ãè¨ããããã¨ã¯ããã.
å¼æ°ã«ãååãã¤ããªã
ã ãã ãæ¸ãã®ã大å¤ã«ãªã£ã¦ããã®ã§, ãã£ããã©ã ãè¨ç®ã®è¨æ³ãæ··ãã¦å§ç¸®ãã¦æ¸ãã¦ãã. æ¡ä»¶åå²ãååæ¼ç®ã¯ãã®ã¾ã¾.
let Z = λf.(λx.f (λy.x x y)) (λx.f (λy.x x y)) Z (λfn.n <= 1 ? 1 : n * (f (n - 1)))
å¼æ°ãååã§è¡¨ç¾ããã®ãããã¦, ããã¶#
ã##
ãªã©ã¨æ¸ããã¨ã«ãã. #
ã®åæ°ããããã¤å¤å´ã®Î»ã«ããå¤æ°æç¸ããã表ãããã«ãã.
let Z = λ (λ ## (λ ## ## #)) (λ ## (λ ## ## #)) Z (λλ # <= 1 ? 1 : # * (## (# - 1)))
Z
ãååãã¤ããã®ãããã.
(λ (λ ## (λ ## ## #)) (λ ## (λ ## ## #))) (λλ # <= 1 ? 1 : # * (## (# - 1)))
ãã£ãã¼! ååããã£ãããªããªã£ã!
ãã®è¡¨ç¾ã®ä»æ¹ã¯De Bruijn indexã¨å¼ã°ãã¦ãã.
De Bruijn indexã¯ååã§ã¯ãªãã®ã?
ä»åã¯(æ°å¤ãç»å ´ãã¦ç´ããããã®ã§)#
ã®åæ°ã§De Bruijn indexã表ç¾ãããã©, ãµã¤ãã¯åã«æ°åã使ã. ãã®å ´å, æ°åã¯ååã§ã¯ãªãã®ã? ååã¯ããããèªç¶æ°ã¨1対1ã«å¯¾å¿ãã¤ãããã(èªç¶æ°ã¨åå)ã ãããã, æ°åã§è¡¨ç¾ãããã¨ã¨ååãã¤ãããã¨ã¯ã¤ã³ã¼ã«ã§ã¯ãªãã®ã?
De Bruijn indexãååã ã¨æãã¨å°ãããããªã¨ããããã£ã¦, ããã¯å¼ãè©ä¾¡ãããã¨ååãã©ãã©ãå¤ãã£ã¦ãã¾ãç¹. ãã¨ãã°
λ (λλ ## #) #
ã¨ããå¼ã®1段å å´ã®é¢æ°é©ç¨ãç°¡ç´ããã¨
λλ ## #
ã¨ãªã, #
ã ã£ããã®ã##
ã«å¤ãã£ã¦ãã¾ã. ãããªã³ãã³ãå¤ãã£ã¦ãã¾ããã®ãååã¨è¨ã£ã¦ããã®ã?? ååã¨ã¯ãªããªã®ã ???
éã«ååã§ã¯ãªãã¨ããã, ããããããããååãªã®ãããããªããååãã©ããã¨ãã話ã¯ãã£ããå¿ãã¦, ãã®De Bruijn indexã¨ã¯ãªããªã®ãã¨è¨ãã¨, λé ãã°ã©ãã§è¡¨ç¾ããã¨ãã®æç¸é¢ä¿ã表ã辺ã«ãªã£ã¦ãã.
graph TD Lx((λ)) --- Ly((λ)) Ly --- Lz((λ)) Lz --- y(( )) y -.->|##| Ly Lz --- z(( )) z -.->|#| Lz Lx --- x(( )) x:::red -.->|#| Lx classDef red fill:#ff3366, stroke:#993366;
graph TD Lx((λ)) --- Lz((λ)) Lz --- y(( )) y:::red -.->|##| Lx Lz --- z(( )) z -.->|#| Lz classDef red fill:#ff3366, stroke:#993366;
ãååãã¨è¨ãã¨ãã¼ããã®ãã®ã«ã©ãã«ãä»ãã¦ãã¦ã»ããæããããã, ãã¼ããã®ãã®ã§ã¯ãªãä»ã®ãã¼ãã¨ã®é¢ä¿ã«ã¤ããã©ãã«ã ãã, ãã¾ãååã£ã½ãã¯ãªã. ã¾ãå¤æ°åã§ãªãã¨ããã ãã§é¢ä¿ã表ãååãªã®ã ã¨å¼·å¼ãããã, ãããããããªããã©.
ååããã£ããã¤ããªãããã°ã©ãã³ã°è¨èª
ã§ã¯ããååã¯ãã£ããããã¦ãã¾ãã. コンビネータ計算ã«å¾ã£ã¦ä½ãããLazy Kã®ãããªè¨èªã§ã¯, è¨èªã®ããªããã£ãã¯åºæ¬çã«S
ãK
ã¨ãã£ãã³ã³ããã¼ã¿ã®ã¿ã§, å¤æ°åã¨ããæ¦å¿µããªã. ãã®è¨èªã§æ¸ã人ãä½ããåä»ããã¨ãããã¨ã¯ãªã.
ã³ã³ããã¼ã¿è¨ç®ã¯ãã¥ã¼ãªã³ã°å®å
¨ãªã®ã§, å帰çã«è¨ç®ããé¢æ°ã§ãã£ã¦ã表ç¾ã§ãã. ãããã¯ä¸åç¹ã³ã³ããã¼ã¿ãã®ãã®ã以ä¸ã®ããã«ã³ã³ããã¼ã¿ã®å¼ã§æ¸ã表ãã(I
ã¯(S K K)
ã®ç¥).
Y = S (K (S I I)) (S (S (K S) K) (K (S I I)))不動点コンビネータ - Wikipedia
ãããç´ã«æ¸ãä¸ãã«ã¯ãã«ãã«ãè³*2ã«ãªãå¿ è¦ããã£ã¦é ã®ä½æã©ããã§ã¯ãªããã©, 幸ããªãã¨ã«任意のλ項はコンビネータの式に機械的に変換できる. ããããå¤æã使ã£ã¦階乗を計算するプログラムをLazy Kで書いている人ããã.
ãããã£ãããã°ã©ãã³ã°è¨èªãåå¨ãã以ä¸, ãé¢æ°ã®å帰çãªå®ç¾©ãå®ç¾ããã®ã«ååä»ãã¯å¿ è¦ã?ãã¨åãããã°Noã¨è¨ããããå¾ãªã.
ããããã©ããã話ã ã£ãã®ã
ãã¨ãã¨ã¯, ããããã記号と再帰ãã¨ããæ¸ç±ããã®å¼ç¨ã§, å帰ãè¨å·è«çã«æããã¨ã©ããªããã¨ãã話ã ã¨æã.
ãããã¨ããããã¾ããä¸åç¹é¢æ°ãå©ç¨ãã¦å帰ãéå帰çã«ããã¨ãããã®ä¸åç¹é¢æ°ãä¸é é¢ä¿ãæã£ã¦ãã¦ããã®ä¸æ¬¡æ§ãæã¤å¯¾è±¡ãåç¯ããä¸ã§è¨å·ã大ããªå½¹å²ãæããã¨ã®ãã¨ã§ãããã¾ã å®å ¨ã«ç解ã§ãã¦ã¾ããããååã¥ãã¨ä¸åç¹é¢æ°ãå©ç¨ãããã¨ã«ãæ¬è³ªçãªç¹ãããããããã§ã
— naoya (@naoya_ito) 2022å¹´8æ12æ¥
ãè¨å·ã¨å帰ãã¯èªãã§ããªãã®ã§ãä¸é ãã¨ããã®ããªãã®ãã¨ãªã®ãã¡ãã£ã¨ããããããªããã©, ãããã話ã ããã??
è¨å·è«ï¼ã»ããªãã£ã¯ã¹ï¼ã¯ããã£ã¼ã«ãºã»ãµã³ãã¼ã¹ã»ãã¼ã¹ã«ãããã表ç¾ãå 容ãæ示対象ãã®ä¸é ã«åºã¥ãè¨å·å¦ã§ããã
記号学 - Wikipedia
ã ã¨ããã¨, De Bruijn indexã§ç¡ååããã¨ãããããã¾ã§ã¯, ç¡åã§ã¯ãããã®ã®ãæ示対象ãã¿ãããªè©±ã¯å¥å¨ã§, ããããªãã§ã¯ãªã. ãã ããã¯å帰ãã©ããã¯ãã¾ãé¢ä¿ãªã, ãå¤æ°æç¸ãã¨ããæ¦å¿µã®ããã©ã ãè¨ç®ã§ã¯é¿ãã¦éããªã(ããå帰ãæ¸ããªãåç´åä»ã©ã ãè¨ç®ã§ããæ示対象ãã¿ãããªãã®ã¯æ¬è³ªçã«åå¨ãã¦ãããã¨ã«ãªãã¯ã).
ããã©ã³ã³ããã¼ã¿è¨ç®ã¾ã§ããã¨ãªãã ãããããããªããªã£ã¦ãã. ãã¶ããã«ãã«ãæµã®è«çä½ç³»ã®è¨å·è«ç解éã¿ãããªãã®ãã¡ããã¨èããªãã¨, ããããèªæã§ã¯ãªãæ°ããã.
è¨å·è«ã«ã¤ãã¦ã¯ããããããç¥ããªãã®ã§é çæ¼¢ãªãã¨ãè¨ã£ã¦ãããããããªã. ãååãä»ãããã¨ã§, ä¸åç¹ã³ã³ããã¼ã¿ã¿ãããªå¤§å¤ãªãã®ãæã¡åºããã¨ã, å帰ãèªç¶ã«è¡¨ç¾ã§ãããããããã®è©±ã§ããã°ãããã ããã¨æã.
è¿½è¨ 2022-08-18T11:20:27+09:00
ãããã¨ããããã¾ããä¸é ãã®ã¨ããã¯ã¨ã³ããªã§å¼ç¨ãã wikipedia ã«ããã¨ãããã¼ã¹ã®è¨å·è«ã®ä¸é ã§ãããªã®ã§ãè«ç¹ã¯çµã³ã«ãããååãã¤ããã°èªç¶ã«è¡¨ç¾ã§ãããã(ããã¯ãã) ã¨ããã¨ããã§ã¯ãªããã®å段ã®ãæ示対象ãäºã ã®ã¨ããã«ãªãã¨æãã¾ãã
— naoya (@naoya_ito) 2022å¹´8æ17æ¥
è¿½è¨ 2022-08-18T12:05:27+09:00
ã³ã³ããã¼ã¿è¨ç®ãé ã®æ§é ãå ¨ãç°ãªããã«ãã«ãæ人ã¨ãã«ã¯èªç¶ãªå¯è½æ§ã¯ãããã人é¡ã«ã¨ã£ã¦ã¯ä¸èªç¶ã§ã人é¡ã®ããã®ãã¼ã«ã§ããè¨å·è«ãé©ç¨ã§ããªãã¨è¨ããã¦ãä¸æè°ã§ã¯ãªã
— INA Lintaro (@oarat) 2022å¹´8æ18æ¥
è¿½è¨ 2022-08-18T13:30:12+09:00
id:mandel59ããã®ããã¯ãã¼ã¯ã³ã¡ã³ã:
é¢æ°ã®å帰çãªå®ç¾©ã«ååä»ãã¯å¿ è¦ã - 貳佰ä¼æ¾é¸å¤æ¥è¨ãããããè¨å·ã¨å帰ãã«ä¸åç¹é¢æ°ã®è©±ãåºã¦ãã¦ãæçµçã«ãä¸æ¬¡æ§ã¯ä¸åç¹é¢æ°ã§ãããã¨ã示åãããã(7.6) ã£ã¦æ¸ãã¦ããã ããª
2022/08/18 13:07
ãã¼, 話ã®æµãã®åãã¯ãã£ã¡åããªãã§ãã. è¨å·è«ã«ããã3次æ§(ã£ã¦ããã®ã¯ä¸é ã®ã3ãã®ãã¨ã¨è§£éãã¦ã¾ã)ã¯, ä¸åç¹é¢æ°(ã«èµ·å ãã?)ã¨æããã¨ãã§ãããããããªã, ã£ã¦è©±ãªããã§ããã? (ãã®ä¸»å¼µãæ£ãããã¯ã¨ããã)ãããªãè¨ããããã¨ã¯ãããã, ããã¶ã³ã³ããã¼ã¿ã§æ¸ããå ´åã¯ãã¾ãé¢é£æ§ããªããªã£ã¦è¦ãããã©ã¨ãã«åé¡ã¯ãªãã§ãã. éã®, ããã°ã©ãã³ã°ã«ãããå帰(ãä¸åç¹é¢æ°)ã®æ§è³ªã¯è¨å·è«ã®ä¸é é¢ä¿ã«å¸°çãããã¨ãã話ãã¨æã£ã¦ãããããããã§ããªãå ´åããããããã¨æã£ã¦ãã¾ã£ã¦ããã®ã§ãã. ã¤ã¾ãå帰ãè¨å·è«çã«è§£éãã¦ããã®ã§ã¯ãªã, è¨å·è«ãå帰ãä¸åç¹ã使ã£ã¦èª¬æãã¦ãã, ã¨.
*1:è¨èªå¦çç³»ãæ¸ãã¦ã¿ãã¨ããããããã¦, å¤æ°ã®å®ç¾©ãå¦çãããã¨ããã, å ·ä½çãªå®ç¾©ã¯ã¾ã ããããªã段éã§å¤æ°åã¨ãããæãå®ç¾©(ãå¾ã§å ¥ãã¯ãã®å ¥ãç©)ããã£ããç°å¢ã«ç©ãå¿ è¦ããã
*2:æ®éã®è«çã§ã¯ãªããã«ãã«ãæµã®è«çä½ç³»ã§èãããã¨