å帰åå ¥é
ããã®è¨äºã¯Scala Advent Calendar jp 2010 : ATNDã®3æ¥ç®ã®è¨äºã§ããã
å帰ã®è©±ããã¾ãã
ä½ããé£ããã¨æãããã¡ãªå帰ã§ããã
ãã¤ã³ã(ã¨ãããéåã)æ¼ããã¦ãã¾ãã°ã¨ã£ã¦ãç°¡åã§ãã
å帰ã®ãã¤ã³ãã¯2ã¤ã§ãã
- ä¸æ®µéç°¡åãªåé¡ãèããã
- çµãããèããã
ãã£ãããã ãã
ãé£ããåé¡ãå°ããã¤ç°¡åã«ãã¦ããã®ãå帰ãã§ãã
æ¬æ¥ãå帰ã¯é£ããåé¡ã解ãããã®ç°¡åãªæ段ãªã®ã§ãã
å ·ä½çã«
1ãã10ã¾ã§ã®è¶³ãç®ãå帰ã§ã¨ãã¾ãã
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = ?
ã¾ãã¯å帰ã®ãã¤ã³ãã®ä¸ã¤ã
- ä¸æ®µéç°¡åãªåé¡ãèããã
ã«å¾ã£ã¦ã¿ã¾ãããã
1 ãã 10 ã¾ã§ã®è¶³ãç®ããã¡ãã£ã¨ç°¡åãªåé¡ã¯ããã
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = ?
1 ãã 9 ã¾ã§ã®è¶³ãç®ã§ãã
1 ãã 10 ã¾ã§ã®åãæ±ããããã°ã
1 ãã 9 ã¾ã§ã®åãæ±ãã¦ã ããã«10ã足ãã¦ããã°ããã®ã§ãã
å¼ã«ãã¦ã¿ãã¨
sum(10) = sum(9) + 10
ã§ããã
ãããä¸è¬åããã¨
sum(n) = sum(n - 1) + n
scalaã®ã³ã¼ãã«ããã¨
def sum(n: Int): Int = sum(n - 1) + n
ã¨ãªãã¾ãã
ãã³ã
- é·ã¼ãç®æ°ã®åé¡ã¯ã²ã¨ã¤çããã¦èãã¾ããã
- Scalaã®List, List(1, 2, 3, 4, 5) ãªããå é ã®1ãåãåºã㦠List(2, 3, 4, 5) ã«ã¤ãã¦èãã¦ã¿ãã
- Cã®é åã ã£ããããã¤ã³ã¿ãã²ã¨ã¤ãããã¦ã¿ãã
å ¨é¨èããªãã¦ãè¯ãã
å帰ã®ãã°ãããã¨ããã¯1ãã10ã¾ã§èããå¿
è¦ããªããã¨ã§ãã
nçªç®ã¨n+1çªç®ã®é¢ä¿ãè¦ãåºãã ãã§åé¡ã解ãã¦ãã¾ãã®ã§ãã
ã¨ããã§ãä¸å¦æ ¡ãããã§ãæ°å¦ç帰ç´æ³ã«ãã証æããç¿ãã¾ããããã
- N=0ã®ã¨ãã«æ£ãããã¨ã示ãã
- N=Mã®ã¨ãã«æ£ãããã°N=M+1ã«ãæ£ãããã¨ã示ãã
ãããåé¡ã®å帰çãªæ§è³ªãå©ç¨ãã¦ãå
¨ä½ã¯èããã«
Nçªç®ã¨N+1çªç®ã«çç®ãã¦å½é¡ã証æãããã¨ãããã®ã§ããã
å ·ä½ä¾ã«è©±ãæ»ãã¦ã
ãã¤ã³ãã®2ã¤ç®
- çµãããèããã
ãã®åé¡ã®å ´åãã¯nã1ã«ãªã£ããåã1ãèªåçã«çµããã§ããã
ãã®æ¡ä»¶ãå ãã¦ã¿ã¾ãã
def sum(n: Int): Int = { if (n = 1) 1 else sum(n-1) + n }
ããã§ãå帰é¢æ°å®æã§ãã
ãã§ãããã§ããã
ã¨ãããã§ãã®ããã°ã¨ã³ããªãããããã£ã¦ãã¾ãããæ°æã¡ã¯ããã®ã§ããã
ã¡ãã£ã¨ã¾ã£ãã
ãã®é¢æ°ã¯nãå°ããã¨ãã¯ããã®ã§ããã
ãè¨ç®ã®éä¸ã®å¼ããã大éã«ã§ãã¦ãã¾ãããã
nã大ãããªãã¨ãã®ãã¡ã¹ã¿ãã¯ãé£ãæ½°ãã¦ãã¾ãã¾ãã
試ãã«ãã£ã¦ã¿ã¾ããããnãã°ãã§ããããã¨StackOverflowErrorã¨ãªãã¾ãã
æ«å°¾å帰
ãã®å¯¾çã¨ãã¦ãscalaã§ã¯å帰ããæ«å°¾å帰ãã¨ããå½¢ã«ãããã¨ãæ¨å¥¨ããã¾ãã
ãæ«å°¾å帰ãã¨ã¯ç°¡åã«è¨ãã¨ã
ãå帰é¢æ°ã®æå¾ãèªåã®å¼ã³ã ãã®ã¿ã«ãªã£ã¦ããã
ã¨ããç¶æ
ã§ãã
ãªãæ«å°¾å帰ã«ããã¨è¯ãã®ã§ããããã
ããã¯æ«å°¾å帰ã¯ã«ã¼ãã«æ¸ããªãããã¨ãã§ããããã§ãã
æ«å°¾å帰ã®é¢æ°ãæ¸ãã¨ãå¦çç³»ãå
é¨ã§åæã«ã«ã¼ãã«ãã¦ããããããã§ãã
ã«ã¼ããªãã¹ã¿ãã¯ãããµãããã¨ã¯ãªãã§ãããã
ãããæ«å°¾å帰ã®æé©åãã¨è¨ãã¾ãã
ã¡ãªã¿ã«ãä¾ãã°EmacsLispã¯ãæ«å°¾å帰ã®æé©åããã¦ããã¾ããã
èªåã¯EmacsLispããã触ã£ã¦ããã®ã§ãæ«å°¾å帰ï¼ãªã«ããï¼ã£ã¦æãã§ããã
ã§ãScalaã¯æ«å°¾å帰æé©åããã¦ããã¾ãã
ç¶æ å¤æ°
ã¨ããããæ«å°¾å帰ã«ããæ¹æ³ã§ãã
å帰é¢æ°ã®å¼æ°ã«ãç¶æ
å¤æ°ãã¨ããç´¯ç©å¤æ°ãã¨ãå¼ã°ãããã®ãä»ã足ãã¾ãã
import scala.annotation.tailrec @tailrec def sum(n: Int, result: Int = 0): Int = { if (n == 1) result else sum(n-1, n + result) }
ããã§ã¯resultãç¶æ
å¤æ°ã§ãã
ãã®resultã«è¨ç®ã®éä¸çµæãæ ¼ç´ãã¦åãã¾ãã
ããããã°ãå帰çãªå¼ã³ã ããè¡ãªã£ãçµæããã®ã¾ã¾çµæã«ãªãã¾ãã
ãããæ«å°¾å帰é¢æ°ã§ãã
ãªãããããå帰ã£ã¦ãå¤ãªæãã¨ãããããã¯ãã¨ãããã
å人çã«ã¯ããããã¾ãç¾ãããªããªãããã£ãã®ã»ãããããã ãªãã£ã¦æããã§ãããã¾ãããããªãã
@tailrecã¯æ«å°¾å帰ãå¼·å¶ããã¢ããã¼ã·ã§ã³ãããã§ãã
@kirisããã«æãã¦ãããã¾ããã
ãããã¤ããã¨ãæ«å°¾å帰ã«ãªã£ã¦ããªãã¨ã¨ã©ã¼ã«ãªãã¾ãã
ã¾ã¨ã
ã¾ã¨ããã¨ãscalaã§å帰é¢æ°ãæ¸ãå ´åã¯ã
ä¸è¿°ã®å帰ã®ãã¤ã³ãã«å¾ã£ã¦å帰é¢æ°ãæ¸ããæ«å°¾å帰ã«ã§ããå ´åã¯æ«å°¾å帰ã«æé©åããã
ã®ãå®ç³ãã¨ãããã¨ã§ãã
æå¾ã«
å帰é¢æ°ãæ¸ãã®ã¯æ¥½ããã®ã§ããã
1ãã10ã¾ã§ã®åãæ±ããã®ã«å帰ã使ãã¨ãããããããã¨ã¯ããã¾ãããã
(1 + 10) * 10 / 2 = 5050
1 to 10 sum
é©åãªã¢ã«ã´ãªãºã ãé¸ã¶ã®ã大äºã§ãã