Previous Up Next
Chapter 3 ºÆµ¢¤Ë¤è¤ë·«¤êÊÖ¤·

¤³¤Î¾Ï¤Î¥­¡¼¥ï¡¼¥É: ¶É½êÊÑ¿ô¡¤ÁÈ¡¤¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¡¤ºÆµ¢´Ø¿ô

Á°²ó¡¤Èó¾ï¤Ë´Êñ¤Ê´Ø¿ô¤ÎÀë¸ÀÊýË¡¤ò³Ø¤ó¤À¤¬¡¤ËÜÅö¤Ë´Êñ¤Ê¤³¤È¤·¤« ¼Â¸½¤Ç¤­¤Ê¤¤¤³¤È¤Ëµ¤¤Å¤¯¤À¤í¤¦¡¥Î㤨¤Ð¡¤Ê£¿ô¤Î¥Ñ¥é¥á¡¼¥¿¤ò¤È¤ë¤è¤¦¤Ê ´Ø¿ô¤Ï¤É¤Î¤è¤¦¤Ë¤¹¤ì¤Ð¤è¤¤¤Î¤À¤í¤¦¤«¡¥¤Þ¤¿¡¤´Ø¿ôËÜÂΤμ°¤¬Ê£»¨¤Ë¤Ê¤ë¤Ë¤Ä¤ì¡¤ ¤½¤Î°ÕÌ£¤òÄɤ¦¤Î¤¬ÂçÊѤˤʤäƤ¯¤ë¤³¤È¤Ëµ¤¤Å¤¯¤«¤â¤·¤ì¤Ê¤¤¡¥

º£²ó¤Î¼ç¤ÊÆâÍƤϡ¤ºÆµ¢Åª¤Ê´Ø¿ôÄêµÁ¤Ë¤è¤ë·«¤êÊÖ¤·¤Î¼Â¸½¤Ç¤¢¤ë¤¬¡¤ ¤½¤ÎÁ°¤Ë¾¯¤·´ó¤êÆ»¤ò¤·¤Æ¡¤°ì»þŪ¤Ë»ÈÍѤ¹¤ë¶É½êÊÑ¿ô¤ÎÀë¸À¤È¡¤ Ê£¿ô¤ÎÃͤò¤Þ¤È¤á¤Æ°·¤¦¤¿¤á¤Î¥Ç¡¼¥¿¹½Â¤¤Ç¤¢¤ëÁÈ(tuple)¤ò ¤ß¤Æ¤¤¤¯¡¥

3.1 ¶É½êÊÑ¿ô¤Èlet¼°

´Ø¿ô¤ÎËÜÂÎÆâ¤Ç¡¤·×»»¤¬¿ô¥¹¥Æ¥Ã¥×¤ËµÚ¤Ó¼°¤¬Ê£»¨¤Ë¤Ê¤Ã¤Æ¤¯¤ë¤È Éôʬ¼°¤Î°ÕÌ£¤òÊá¤é¤¨¤ë¤³¤È¤¬½ù¡¹¤Ëº¤Æñ¤Ë¤Ê¤Ã¤Æ¤¯¤ë¡¥

Objective Caml¤Ç¤Ïlet-¼°(Àë¸À¤Ç¤Ï¤Ê¤¤)¤Ë¤è¤Ã¤Æ¡¤¶É½êÊÑ¿ô¤òÀë¸À¤·¡¤ Ãͤ˰ì»þŪ¤Ê̾Á°¤ò¤Ä¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥

¤Þ¤º¤Ï¡¤´Êñ¤ÊÎ㤫¤é¸«¤Æ¤¤¤³¤¦¡¥
# let vol_cone = (* Ⱦ·Â 2 ¹â¤µ 5 ¤Î±ß¿í¤ÎÂÎÀÑ *)
#   let base = pi *. 2.0 *. 2.0 in
#   base *. 5.0 /. 3.0;;
val vol_cone : float = 20.9439510233
``let base = '' °Ê²¼¤¬ let ¼°¤Ç¤¢¤ë¡¥base ¤È¤¤¤¦¶É½êÊÑ¿ô¤òÀë¸À¡¤ ÄìÌ̤ÎÌÌÀѤË«Çû¤·¤¿¤¢¤È¤Ç¡¤ÂÎÀѤò·×»»¤·¤Æ¤¤¤ë¡¥(¤½¤Î·ë²Ì¤Ï vol_cone ¤Ë¤Ê¤ë¡¥)

°ìÈÌŪ¤Ê let-¼°¤Î·Á¤Ï
let x = e1 in e2
¤Ç¡¤e1, e2 ¤¬ let ¼°¤Ç¤¢¤Ã¤Æ¤â¤â¤Á¤í¤ó¤è¤¤¡¥ ¤³¤Î¼°¤Ï¡¤
  1. e1¤òɾ²Á¤·¡¤
  2. x ¤ò¤½¤Î·ë²Ì¤Ë«Çû¤·¤Æ¡¤
  3. e2 ¤Îɾ²Á
¤ò¹Ô¤¤¡¤Á´ÂÎ¤Ï e2 ¤Îɾ²Á·ë²Ì¤Ë¤Ê¤ë¡¥ÊÑ¿ô x ¤ÎÍ­¸úÈÏ°Ï¤Ï e2 ¤Ç¤¢¤ë¤Î¤Ç¡¤vol_cone ¤ÎÀë¸À°Ê¹ß¤Ç¤Ï base ¤Ï»²¾È¤Ç¤­¤Ê¤¤¡¥
# base;;
 base;;
 ^^^^
Unbound value base
¤Þ¤¿¡¤e1 ¤Ïx¤ÎÍ­¸úÈϰϤ˴ޤޤì¤Ê¤¤¤³¤È¤ËÃí°Õ¡¥

¤â¤Á¤í¤ó¡¤let-¼°¤Ï´Ø¿ô¤ÎËÜÂΤËÍѤ¤¤ë¤³¤È¤â¤Ç¤­¤ë¡¥¤Þ¤¿¡¤let-¼°¤Ç ¶É½êŪ¤Ë»È¤¦Êä½õŪ¤Ê´Ø¿ô¤òÀë¸À¤¹¤ë¤³¤È¤â¤Ç¤­¤ë¡¥3ÈÖÌܤÎÎã¤Ï¡¤¤½¤Î(¤ä¤ä¿Í¹© Ū¤Ê)Îã¤Ç¤¢¤ë¡¥
# let cone_of_heightTwo r =
#   let base = r *. r *. pi in
#   base *. 2.0 /. 3.0;;
val cone_of_heightTwo : float -> float = <fun>
# let f x =                    (* f(x) = x^3 + (x^3 + 1) *)
#   let x3 = x * x * x in
#   let x3_1 = x3 + 1 in
#   x3 + x3_1;;
val f : int -> int = <fun>
# let g x =                    (* g(x) = x^3 + (x+1)^3 *)
#   let power3 x = x * x * x in
#   (power3 x) * (power3 (x + 1));;
val g : int -> int = <fun>
let-¼°¤Î¤â¤Ã¤È¤âÁÇËѤʰյÁ¤Ï¡¤Éôʬ¼°¤Ë̾Á°¤ò¤Ä¤±¤ë¤³¤È¤Ë¤è¤ëÃê¾Ý²½¤Î ¼êÃʤòÄ󶡤¹¤ë¤³¤È¤Ç¤¢¤ë¡¥¤Þ¤¿Ê£¼¡Åª¤Ç¤Ï¤¢¤ë¤¬¡¤Æ±¤¸Éôʬ¼°¤¬ Ê£¿ô²ó½Ð¸½¤¹¤ë¾ì¹ç¤Ë¤½¤Îɾ²Á¤ò1Å٤Ǥ¹¤Þ¤»¤é¤ì¤ë¡¤¤È¤¤¤Ã¤¿¸ú²Ì¤¬ÆÀ¤é¤ì¤ë¡¥ ¤Þ¤¿¡¤Éôʬ¼°¤Î·×»»ÊýË¡¤¬»÷¤Æ¤¤¤ë¾ì¹ç¤Ë¤Ï¡¤¥Ñ¥é¥á¡¼¥¿Ãê¾Ý¤ò»È¤Ã¤Æ¡¤ ¶É½ê´Ø¿ô¤òÄêµÁ¤¹¤ë¤³¤È¤Ç¡¤¥×¥í¥°¥é¥à¤Î¸«Ä̤·¤¬¤è¤¯¤Ê¤ë¡¥

Ê£¿ô¤ÎÊÑ¿ôÀë¸À
let Àë¸À/¼°¤È¤â¤Ë¡¤and ¥­¡¼¥ï¡¼¥É¤ò»È¤Ã¤Æ¡¤ Ê£¿ô¤ÎÊÑ¿ô¤òƱ»þ¤ËÀë¸À¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥
# let x = 2 and y = 1;;
val x : int = 2
val y : int = 1
# (* swap x and y; 
#    the use of x is bound to the previous declaration! *)
# let x = y and y = x;;
val x : int = 1
val y : int = 2
# let z =
#   let x = "foo" 
#   and y = 3.1 in 
#   x ^ (string_of_float y);;
val z : string = "foo3.1"
³ÆÊÑ¿ô¤Î»ÈÍѤ¬¤É¤³¤ÎÀë¸À¤ò»²¾È¤·¤Æ¤¤¤ë¤«¤ËÃíÌÜ¡¥

let-¼°¡¤´Ø¿ô¸Æ½Ð¤·¤È´Ä¶­
Âç°èÊÑ¿ô¤òÀë¸À¤¹¤ëlet-Àë¸À¤Ï¡¤Âç°è´Ä¶­¤ÎËöÈø¤ËÊÑ¿ô¤Î«Çû¤òɽ¤¹¥Ú¥¢ ¤òÄɲ䷤Ƥ¤¤¯¤â¤Î¤Ç¤¢¤Ã¤¿¡¥ ¤³¤ì¤ËÂФ·¡¤let x = e1 in e2 ¤Î¾ì¹ç¡¤x¤Î¥¨¥ó¥È¥ê¤¬Äɲ䵤ì¤ë ¤Î¤Ïe2¤Îɾ²Á¤ò¤¹¤ë°ì»þŪ¤Ê´Ö¤À¤±¤Ç¤¢¤ë¡¥¤³¤ÎÄɲ䵤ì¤ë´ü´Ö ¤¬¡¤Í­¸úÈϰϤËÂбþ¤·¤Æ¤¤¤ë¡¥

ÊÑ¿ô̾ ÃÍ
sin Àµ¸¹´Ø¿ô
max_int 1073741823
ÊÑ¿ô̾ ÃÍ
sin Àµ¸¹´Ø¿ô
max_int 1073741823
x 5
ÊÑ¿ô̾ ÃÍ
sin Àµ¸¹´Ø¿ô
max_int 1073741823
3+2 ¤Îɾ²ÁÃæ¤Î´Ä¶­ x+7 ¤Îɾ²ÁÃæ¤Î´Ä¶­ ²Ã»»(5+7)¼Â¹Ô¸å¤Î´Ä¶­

Figure 3.1: ¼° let x = 3 + 2 in x + 7 ¤Î¼Â¹Ô¡¥Æó½ÅÀþ°Ê²¼¤¬°ì»þŪ¤ËȯÀ¸¤·¤¿Â«Çû¤òɽ¤¹¡¥


¤Þ¤¿´Ø¿ô¸Æ½Ð¤·¤Î¼Â¹Ô¤â¤³¤ì¤È»÷¤Æ¤¤¤Æ¡¤¥Ñ¥é¥á¡¼¥¿¤ò¼Â°ú¿ô¤Ë «Çû¤·¤ÆËÜÂΤμ¹Ԥò¹Ô¤¦¡¥¤¿¤À¤·¡¤Í­¸úÈϰϤÏÀÅŪ¤Ë·è¤Þ¤ë¤¿¤á¡¤ ´Ø¿ô¤¬ÄêµÁ¤µ¤ì¤¿»þÅÀ¤Ç¤Î´Ä¶­¤òÍѤ¤¤ÆËÜÂΤòɾ²Á¤¹¤ë¡¥
let pi = 3.1415926535;;
let c_area(r) = r *. r *. pi;;
let pi = 1;;
let area = c_area 2.0;;
¤Î let area = c_area 2.0 ¤Î¼Â¹ÔÃæ¤Î´Ä¶­¤Ï¡¤¿Þ3.2¤Î ¤è¤¦¤Ëɽ¤µ¤ì¤ë¡¥´Ø¿ôËÜÂÎɾ²ÁÃæ¤Î´Ä¶­¤ËÃí°Õ¤¹¤ë¤³¤È¡¥

ÊÑ¿ô̾ ÃÍ
pi 3.1415926535
c_area <fun>
pi 1
ÊÑ¿ô̾ ÃÍ
pi 3.1415926535
r 2.0
ÊÑ¿ô̾ ÃÍ
pi 3.1415926535
c_area <fun>
pi 1
area 12.566370614
c_area 2.0 ¸Æ½Ð¤·Ä¾Á°¤Î´Ä¶­ ´Ø¿ô¸Æ½Ð¤·Ä¾¸å¤Î´Ä¶­ ¼Â¹Ô½ªÎ»¸å¤Î´Ä¶­

Figure 3.2: ¼° let area = c_area 2.0 ¤Î¼Â¹Ô¡¥Æó½ÅÀþ°Ê²¼¤¬°ì»þŪ¤ËȯÀ¸¤·¤¿Â«Çû¤òɽ¤¹¡¥


3.1.1 Îý½¬ÌäÂê

Exercise 1  ¼¡¤Î³Æ¼°¤Ë¤ª¤¤¤Æ¤½¤ì¤¾¤ì¤ÎÊÑ¿ô¤Î»²¾È¤¬¤É¤ÎÄêµÁ¤ò»Ø¤¹¤«¤ò¼¨¤»¡¥ ¤Þ¤¿É¾²Á·ë²Ì¤ò¡¤¤Þ¤º¥³¥ó¥Ñ¥¤¥é¤ò»È¤ï¤º¤ËͽÁÛ¤»¤è¡¥¤½¤Î¸å¤Ç ¼ÂºÝ¤Ë³Î¤«¤á¤è¡¥
  1. let x = 1 in let x = 3 in let x = x + 2 in x * x
  2. let x = 2 and y = 3 in (let y = x and x = y + 2 in x * y) + y
  3. let x = 2 in let y = 3 in let y = x in let z = y + 2 in x * y * z

Exercise 2  ¥È¥Ã¥×¥ì¥Ù¥ë¤Ç¤Î°Ê²¼¤Î2¼ïÎà¤ÎÀë¸À¤Î°ã¤¤¤Ï²¿¤«¡©(¥Ò¥ó¥È: e2 ¤¬x¤ò´Þ¤à¾ì¹ç¤ò¹Í¤¨¤è¡¥)

3.2 ¹½Â¤¤Î¤¿¤á¤Î¥Ç¡¼¥¿·¿: ÁÈ

¼¡¤Ë¡¤Ê£¿ô¤ÎÃͤò¤Þ¤È¤á¤Æ°·¤¦ÊýË¡¤ò¸«¤ë¤³¤È¤Ë¤¹¤ë¡¥¤³¤ì¤Ë¤è¤Ã¤Æ Ê£¿ô¤Î¥Ñ¥é¥á¡¼¥¿¤ò¼è¤ë´Ø¿ô¡¤Ê£¿ô¤Î·ë²Ì¤òÊÖ¤¹´Ø¿ô¤òÄêµÁ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥

3.2.1 ÁȤòɽ¤¹¼°
¿ô³Ø¤Ç¤Ï¡¤¥Ù¥¯¥È¥ë¤Î¤è¤¦¤Ë¡¤Ê£¿ô¤Î¡Ö¤â¤Î¤Î½¸¤Þ¤ê¡×¤«¤é¡¤¤½¤ì¤¾¤ì¤ÎÍ×ÁǤò ʤ٤¿¤â¤Î¤òÍ×ÁǤȤ¹¤ë¤è¤¦¤Ê¡¤¿·¤¿¤Ê½¸¤Þ¤ê(½¸¹ç¤Î¸ÀÍդǤ¤¤¨¤Ð(¥Ç¥«¥ë¥È)ÀÑ)¤òÄêµÁ ¤¹¤ë¤³¤È¤¬¤¢¤ë¡¥¤½¤ì¤ÈƱ¤¸¤è¤¦¤Ë Objective Caml ¤Ç¤âÊ£¿ô¤ÎÃͤòʤ٤ơ¤¿·¤·¤¤¤Ò¤È¤Ä¤ÎÃͤòºî¤ë ¤³¤È¤¬¤Ç¤­¤ë¡¥¤³¤Î¤è¤¦¤ÊÃͤòÁÈ(tuple)¤È¸Æ¤Ö¡¥tuple ¤Ï¡¤() Æâ¤Ë¡¤¼°¤ò , ¤Ç¶èÀڤäÆʤ٤Æɽµ­¤¹¤ë¡¥
# (1.0, 2.0);;
- : float * float = (1., 2.)
·ë²Ì¤Î·¿ float * float ¤Ï¤³¤ÎÃͤ¬¡¤¡ÖÂè1Í×ÁÇ (1.0) ¤¬ float ¤Ç¡¤ Âè2Í×ÁÇ(2.0)¤â float ¤Ç¤¢¤ë¤è¤¦¤ÊÁȡפǤ¢¤ë¤³¤È¤ò¼¨¤¹¡¥* ¤ÏÁȤη¿¹½ÃÛ»Ò ¤Ç¤¢¤ë¡¥

ÁȤȤ·¤Æʤ٤é¤ì¤ëÍ×ÁǤÏÆó¤Ä°Ê¾å(¥á¥â¥ê¤Îµö¤¹¸Â¤ê)¤¤¤¯¤Ä¤Ç¤â ¤è¤¯¡¤¤Þ¤¿Æ±¤¸·¿¤Î¼°¤Ç¤Ê¤¯¤Æ¤â¤è¤¤¡¥¤Þ¤¿¡¤¤â¤Á¤í¤ó¾¤ÎÃͤÈƱÍÍ¤Ë let ¤Ç̾Á° ¤ò¤Ä¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥
# let bigtuple = (1, true, "Objective Caml", 4.0);;
val bigtuple : int * bool * string * float = (1, true, "Objective Caml", 4.)
# let igarashi = ("Atsushi", "Igarashi", 1, 16)
#         (* Igarashi was born on January 16 :-) *);;
val igarashi : string * string * int * int = ("Atsushi", "Igarashi", 1, 16)
3.2.2 ¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤ÈÍ×ÁǤÎÃê½Ð
ÁȤÎÃæ¤ÎÃͤ˥¢¥¯¥»¥¹¤¹¤ë¤Ë¤Ï¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á(pattern matching) ¤Îµ¡Ç½¤ò»È¤¦¡¥¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤Î³µÇ°¤Ï UNIX ¤Î grep ¤Ê¤É¤Î¥³¥Þ¥ó¥É¤Ç¤â¤ß¤é¤ì¤ë ¤¬¡¤¤ª¤ª¤¶¤Ã¤Ñ¤Ë¤Ï
  1. ¥Ç¡¼¥¿¤ÎÉôʬŪ¤Ê¹½Â¤¤òµ­½Ò¤·¤¿¼°(¥Ñ¥¿¡¼¥ó)¤«¤é¡¤
  2. Í¿¤¨¤é¤ì¤¿¥Ç¡¼¥¿¤Î¹½Â¤¤ÈÈæ¤Ù¤ë¤³¤È¤Ç¡¤
  3. ¥Ñ¥¿¡¼¥óµ­½Ò»þ¤Ë¤ÏÉÔÌÀ¤À¤Ã¤¿Éôʬ¤ò´Êñ¤ËÃΤ롦»È¤¦¤³¤È¤¬¤Ç¤­¤ë¡¥
¤è¤¦¤Êµ¡Ç½¤Ç¤¢¤ë¤È¤·¤Æ¤è¤¤¤À¤í¤¦1¡¥ Î㤨¤Ð¡¤(x, y, z, w)¤È¤¤¤¦¥Ñ¥¿¡¼¥ó¤Ï¡¤4Í×ÁǤ«¤é¤Ê¤ëÁÈ(Í×ÁǤη¿¤Ï ²¿¤Ç¤â¤è¤¤!)¤Ë¥Þ¥Ã¥Á¤·¡¤x ¤òÂè1Í×ÁǤË, y ¤òÂè2Í×ÁǤË, z ¤òÂè3Í×ÁǤˡ¤ w ¤òÂè4Í×ÁǤˤ½¤ì¤¾¤ì«Çû¤¹¤ë¥Ñ¥¿¡¼¥ó¤Ç¤¢¤ë¡¥ ¥Ñ¥¿¡¼¥ó¤ÏÊÑ¿ô¤Î«Çû(let, ´Ø¿ô¤Î¥Ñ¥é¥á¡¼¥¿)¤ò ¤¹¤ë¤È¤³¤í¤Ë»ÈÍѤǤ­¤ë¡¥Àè¤Û¤É¤Î¡¤bigtuple ¤ÎÍ×ÁǤϡ¤
# let (i, b, s, f) = bigtuple;;
val i : int = 1
val b : bool = true
val s : string = "Objective Caml"
val f : float = 4.
¤Î¤è¤¦¤Ë¤·¤Æ¡¤¼è¤ê½Ð¤¹¤³¤È¤¬¤Ç¤­¤ë¡¥

¸·Ì©¤Ë¤Ï¾å¤Î¥Ñ¥¿¡¼¥ó¤Ï 4¤Ä¤ÎÊÑ¿ô¥Ñ¥¿¡¼¥ó¤ÈÁȥѥ¿¡¼¥ó¤ò»È¤Ã¤Æ¹½À®¤µ¤ì¤ëÊ£¹ç Ū¤Ê¥Ñ¥¿¡¼¥ó¤Ç¤¢¤ë¡¥ÊÑ¿ô¥Ñ¥¿¡¼¥ó¤Ïº£¤Þ¤Ç»È¤Ã¤Æ¤­¤¿ let x = ... ¤Ê¤É¤Î¤â¤Î¤Ç¡¤¥Ñ¥¿¡¼¥ó¤È¤·¤Æ ²ò¼á¤¹¤ë¤È¡¤¡Ö²¿¤Ë¤Ç¤â¥Þ¥Ã¥Á¤·¡¤x ¤ò¥Þ¥Ã¥Á¤·¤¿ÃͤË«Çû¤¹¤ë¡×¤â¤Î ¤Ç¤¢¤ë¡¥Áȥѥ¿¡¼¥ó¤Ï¡¤(⟨ ¥Ñ¥¿¡¼¥ó1, ...,⟨ ¥Ñ¥¿¡¼ ¥ón) ¤È¤¤¤¦·Á¤Ç¤è¤ê¾®¤µ¤¤Éôʬ¥Ñ¥¿¡¼¥ó¤«¤é¹½À®¤µ¤ì¤ë¡¥ ¥Ñ¥¿¡¼¥ó¤È¤·¤Æ¤Î²ò¼á¤Ï¡¤¡Ön¸Ä¤ÎÁȤǡ¤¤½¤ì¤¾¤ì¤ÎÍ×ÁǤ¬ ⟨ ¥Ñ¥¿¡¼¥ói ⟩¤Ë¥Þ¥Ã¥Á¤¹¤ë¤È¤­Á´ÂΤ¬¥Þ¥Ã¥Á¤·¡¤Éôʬ¥Ñ¥¿¡¼¥ó¤¬ºî¤ë«Çû¤ÎÁ´ÂΤò ¥Ñ¥¿¡¼¥óÁ´ÂΤΫÇû¤È¤¹¤ë¡×¤È¤Ê¤ë¡¥¤Þ¤¿¡¤¤Ò¤È¤Ä¤Î¥Ñ¥¿¡¼¥óÃæ ¤ËÊÑ¿ô¤Ï¤¿¤À1ÅÙ¤·¤«¸½¤ì¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¡¥Î㤨¤Ð¡¤ÁÈÃæ¤Î ¤Õ¤¿¤Ä¤ÎÍ×ÁǤ¬Åù¤·¤¤¤³¤È¤ò¥Ñ¥¿¡¼¥ó¤Çɽ¤¹¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡¥
# (* matching against a person whose first and family names are the same *)
# let (s, s, m, d) = igarashi;;
 let (s, s, m, d) = igarashi;;
 ^
This variable is bound several times in this matching
¤â¤¦¤Ò¤È¤Ä¡¤¥Ñ¥¿¡¼¥ó¤ò¾Ò²ð¤·¤è¤¦¡¥ ¾å¤ÎÎã¤Ç¤Ï¡¤Á´Éô¤ÎÍ×ÁǤË̾Á°¤ò¤Ä¤±¤Æ¤¤¤ë¤¬¡¤¥×¥í¥°¥é¥à¤ÎÉôʬ¤Ë¤è¤Ã¤Æ¤Ï°ìÉô ¤ÎÍ×ÁǤÀ¤±¼è¤ê½Ð¤»¤Ð¤è¤¤¾ì¹ç¤â¤¢¤ë¡¥¤³¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¡¤ÊÑ¿ô¤ÎÂå¤ê¤Ë¡¤ _ (¥¢¥ó¥À¡¼¥¹¥³¥¢)¤È¤¤¤¦ ¡Ö²¿¤Ë¤Ç¤â¥Þ¥Ã¥Á¤¹¤ë¤¬¥Þ¥Ã¥Á¤·¤¿ÆâÍƤϼΤƤë¡× ¥ï¥¤¥ë¥É¥«¡¼¥É¥Ñ¥¿¡¼¥ó(wildcard pattern)¤È¸Æ¤Ö¥Ñ¥¿¡¼¥ó¤ò»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥
# let (i, _, s, _) = bigtuple;;
val i : int = 1
val s : string = "Objective Caml"
3.2.3 ÁȤòÍѤ¤¤¿´Ø¿ô
¼¡¤Ë¡¤float ¤Î¥Ú¥¢(2Í×ÁǤÎÁÈ)¤«¤é³ÆÍ×ÁǤÎÊ¿¶Ñ¤ò¤È¤ë´Ø¿ô¤òÄêµÁ¤·¤Æ¤ß ¤è¤¦¡¥¥Ñ¥é¥á¡¼¥¿¤òº£¤Þ¤Ç¤Î¤è¤¦¤ËÊÑ¿ô¤È¤¹¤ëÂå¤ê¤Ë¥Ñ¥¿¡¼¥ó¤òÍѤ¤¤Æ¡¤
# let average (x, y) = (x +. y) /. 2.0;;
val average : float * float -> float = <fun>
¤ÈÀë¸À¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥average ¤Î·¿ float * float -> float ¤Ï ¡Ö¼Â¿ô¤Î¥Ú¥¢ float * float ¤ò¼õ¤±¼è¤ê¡¤¼Â¿ô¤òÊÖ¤¹¡×¤³¤È¤ò¼¨¤·¤Æ¤¤¤ë¡¥ (·¿¹½ÃÛ»Ò * ¤ÎÊý¤¬ -> ¤è¤ê¶¯¤¯·ë¹ç¤¹¤ë¤Î¤Ç¡¤¤³¤Î·¿¤Ï (float * float) -> float ¤ÈƱ¤¸°ÕÌ£¤Ç¤¢¤ë¡¥)¤³¤ì¤ò»È¤Ã¤Æ¡¤¤Õ¤¿¤Ä¤Î¼Â¿ô¤ÎÊ¿¶Ñ¤Ï
# average (5.7, -2.1);;
- : float = 1.8
¤È¤·¤Æµá¤á¤é¤ì¤ë¡¥ ¤³¤Î¤è¤¦¤Ë¡¤ÁȤϡ¤°ú¿ô¤¬Ê£¿ô¤¢¤ë¤è¤¦¤Ê ´Ø¿ô¤òÌÏÊ魯¤ë¤¿¤á¤Ë¤è¤¯ÍѤ¤¤é¤ì¤ë¡¥¤³¤³¤Ç¡¤¤ï¤¶¤ï¤¶¡ÖÌÏÊï¡×¤È½ñ¤¤¤¿¤Î¤Ï¡¤ ¼ÂºÝ¤Ë¤Ï average ¤ÏÁȤò°ú¿ô¤È¤·¤Æ¤È¤ë1°ú¿ô´Ø¿ô¤Ç¤¢¤ë¤«¤é¤Ç¤¢¤ë¡¥ ¤Þ¤¿¡¤¼Â¤Ï Objective Caml ¤Î´Ø¿ô¤Ï¤¹¤Ù¤Æ1°ú¿ô´Ø¿ô¤Ç¤¢¤ë¡¥¤Ä¤Þ¤ê¡¤average ¤Ï
# let pair = (0.34, 1.2);;
val pair : float * float = (0.34, 1.2)
# average pair;;
- : float = 0.77
¤È¤·¤Æ¸Æ¤Ó½Ð¤¹¤³¤È¤â¤Ç¤­¤ë¤Î¤Ç¤¢¤ë¡¥µÕ¤Ë¡¤
# let average pair =
#   let (x, y) = pair in (x +. y) /. 2.0;;
val average : float * float -> float = <fun>
¤ÈÄêµÁ¤¹¤ë¤³¤È¤â¤Ç¤­¤ë2¡¥

ÁȤÎÍ×ÁǤȤ·¤ÆÁȤò»È¤¦¤³¤È¤â¤Ç¤­¤ë¡¥¼¡¤ÎÄêµÁ¤Ï¡¤(2¼¡¸µ)¥Ù¥¯¥È¥ë¤Î²Ã»» ¤ò¤¹¤ë¤â¤Î¤Ç¤¢¤ë¡¥
# let add_vec ((x1, y1), (x2, y2)) = (x1 +. x2, y1 +. y2);;
val add_vec : (float * float) * (float * float) -> float * float = <fun>
¤³¤Î´Ø¿ô¤ÏÎ㤨¤Ð¼¡¤Î¤è¤¦¤Ë¸Æ¤Ó½Ð¤µ¤ì¤ë¡¥
# add_vec ((1.0, 2.0), (3.0, 4.0));;
- : float * float = (4., 6.)
# let (x, y) = add_vec (pair, (-2.0, 1.0));;
val x : float = -1.66
val y : float = 2.2
¤³¤Î´Ø¿ô¤Ï¸«Êý¤Ë¤è¤Ã¤Æ¤Ï¡¤Ê£¿ô¤Î·×»»·ë²Ì(°ú¿ô¤È¤·¤ÆÍ¿¤¨¤é¤ì¤ë¤Õ¤¿¤Ä¤Î ¼Â¿ô¤Î¥Ú¥¢¤Î¡¤Âè1Í×ÁǤÎÏ¡¤¤ÈÂè2Í×ÁǤÎÏÂ)¤òƱ»þ¤ËÊÖ¤·¤Æ¤¤¤ë´Ø¿ô¤È»×¤¦ ¤³¤È¤â¤Ç¤­¤ë¡¥¤³¤Î¤è¤¦¤Ë¡¤ÁȤϡ¤Ê£¿ô¤Î°ú¿ô¤òȼ¤¦´Ø¿ô¤À¤±¤Ç¤Ê¤¯¡¤Ê£¿ô¤Î ·ë²Ì¤òÊÖ¤¹´Ø¿ô¤òÌÏÊ魯¤ë¤Î¤Ë¤â»ÈÍѤµ¤ì¤ë¡¥

3.2.4 Îý½¬ÌäÂê

Exercise 3  2¼Â¿ô¤ÎÁê¾èÊ¿¶Ñ¤ò¤È¤ë´Ø¿ô geo_mean ¤òÄêµÁ¤»¤è¡¥

Exercise 4  2¹Ô2Îó¤Î¼Â¿ô¹ÔÎó¤È2Í×ÁǤμ¿ô¥Ù¥¯¥È¥ë¤ÎÀѤò¤È¤ë´Ø¿ô prodMatVec ¤òÄêµÁ¤»¤è¡¥ ¹ÔÎ󡦥٥¯¥È¥ë¤òɽ¸½¤¹¤ë·¿¤ÏǤ°Õ¤Ç¤è¤¤¡¥

Exercise 5  ¼¡¤Î¤Õ¤¿¤Ä¤Î·¿ ¤Î°ã¤¤¤ò¡¤¤½¤Î·¿¤Ë°¤¹¤ëÃͤΠ¹½À®Ë¡¤È¡¤Í×ÁǤμè½Ð¤·Êý¤«¤é¤ß¤ÆÈæ³Ó¤»¤è¡¥

Exercise 6  let (x : int) = ... ¤Ê¤É¤Î (x : int) ¤â¥Ñ¥¿¡¼¥ó¤Î°ì¼ï¤Ç¤¢¤ë¡¥ ¤³¤Î¥Ñ¥¿¡¼¥ó¤Î°ÕÌ£¤ò¥Æ¥­¥¹¥È¤ËÊï¤Ã¤Æ(²¿¤Ë¥Þ¥Ã¥Á¤·¡¤¤É¤ó¤Ê«Çû¤òȯÀ¸¤µ¤»¤ë ¤«)ÀâÌÀ¤»¤è¡¥

3.3 ºÆµ¢´Ø¿ô

´Ø¿ôÄêµÁ¤ÏºÆµ¢Åª¤Ë¡¤¤Ä¤Þ¤êÄêµÁ¤Î¤Ê¤«¤Ç¼«Ê¬¼«¿È¤ò»²¾È¤¹¤ë¤è¤¦¤Ë¡¤¹Ô¤¦¤³¤È¤â ²Äǽ¤Ç¤¢¤ë¡¥¤³¤Î¤è¤¦¤ÊºÆµ¢´Ø¿ô(recursive function)¤Ï¡¤·«¤êÊÖ¤·¤ò ȼ¤¦¤è¤¦¤Ê·×»»¤òɽ¸½¤¹¤ë¤¿¤á¤ËÍѤ¤¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥

3.3.1 ´Êñ¤ÊºÆµ¢´Ø¿ô

¤Þ¤º¤Ï´Êñ¤ÊÎ㤫¤é¸«¤Æ¤¤¤³¤¦¡¥¼«Á³¿ô n ¤Î³¬¾è n! = 1 × 2 × ⋯ × n ¤ò·×»»¤¹¤ë´Ø¿ô¤ò¹Í¤¨¤ë¡¥¤³¤Î¼°¤òÊ̤θ«Êý¤ò¤¹¤ë¤È¡¤ ¤³¤È¤¬¤ï¤«¤ë¡¥¤³¤ì¤Ï¡¤¼«Ê¬¼«¿È¤ò»È¤Ã¤ÆÄêµÁ¤·¤Æ¤¤¤ëºÆµ¢Åª¤ÊÄêµÁ¤Ç¤¢¤ë¡¥ ¤¿¤À¤·¡¤Â礭¤Ê¿ô¤Î³¬¾è¤Ï¤è¤ê¾®¤µ¤Ê¿ô¤Î³¬¾è¤«¤éÄêµÁ¤µ¤ì¤Æ¤ª¤ê¡¤ 1 ¤Ë´Ø¤·¤Æ¤Ï¡¤¼«Ê¬¼«¿È¤Ë¸ÀµÚ¤¹¤ë¤³¤È¤Ê¤¯ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡¥¤³¤ì¤Ï ºÆµ¢ÄêµÁ¤¬°ÕÌ£¤ò¤Ê¤¹¤¿¤á¤Î¡¤Èó¾ï¤Ë½ÅÍפʥݥ¤¥ó¥È¤Ç¤¢¤ë¡¥ ¤³¤Îµ¬Â§¤ò Objective Caml ¤ÇÄêµÁ¤¹¤ë¤È¡¤
# let rec fact n = (* factorial of positive n *)
#   if n = 1 then 1 else n * fact (n-1);;
val fact : int -> int = <fun>
¤È¤Ê¤ë¡¥´Ø¿ôËÜÂÎÃæ¤Ë fact ¤¬½Ð¸½¤·¤Æ¤¤¤ë¤³¤È¤¬¤ï¤«¤ë¤À¤í¤¦¡¥ ¤Þ¤¿¡¤¾å¤Ç½Ò¤Ù¤¿µ¬Â§¤¬ÁÇľ¤Ë¥×¥í¥°¥é¥à¤µ¤ì¤Æ¤¤¤ë¤³¤È¤¬¤ï¤«¤ë¡¥ ¤³¤Î fact ¤ÏÀµ¤ÎÀ°¿ô¤ËÂФ·¤Æ¤Ï¡¤Àµ¤·¤¤Åú¤¨¤òÊÖ¤¹¡¥
# fact 4;;
- : int = 24
°ìÈ̤ˤϡ¤ºÆµ¢´Ø¿ô¤òÄêµÁ¤¹¤ëºÝ¤Ë¤Ï¥­¡¼¥ï¡¼¥É rec ¤ò let ¤Î¸å¤Ë¤Ä¤±¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³¤È°Ê³°¡¤Ê¸Ë¡¤ÏÉáÄ̤δؿôÄêµÁ¤È Ʊ¤¸¤Ç¤¢¤ë¡¥¤Þ¤¿¡¤rec ¤¬Í­¸ú¤Ê¤Î¤Ï´Ø¿ôÀë¸À¤Î¤ß¤Ç¤¢¤ë4¡¥
# let rec x = x + 1;;
 let rec x = x + 1;;
 ^^^^^
This kind of expression is not allowed as right-hand side of `let rec'
ºÆµ¢´Ø¿ô¤òÄêµÁ¤¹¤ëºÝ¤Ë¤Ï¡¤¤³¤Î³¬¾è¤ÎÎã¤Î¤è¤¦¤Ë¡¤²¿¤é¤«¤Î°ÕÌ£¤Ç °ú¿ô¤¬¸º¾¯¤·¤Æ¤¤¤¯¤³¤È¤¬½ÅÍפǤ¢¤ê¡¤¼ÂºÝ¤Î´Ø¿ôÄêµÁ¤Ï ¤È¤ò¾ì¹ç¤ï¤±¤ò»È¤Ã¤ÆÁȤ߹ç¤ï¤»¤ë¤³¤È¤«¤é¤Ê¤ë¡¥

3.3.2 ´Ø¿ôŬÍѤÈɾ²ÁÀïά

¤µ¤Æ¡¤¤³¤ì¤Þ¤Ç¤Ë¡¤¼°¤ÏÃͤËɾ²Á¤µ¤ì¤ë¤³¤È¡¤´Ø¿ôŬÍѼ° ¤Ï¡¤¥Ñ¥é¥á¡¼¥¿¤ò¼Â°ú¿ô¤ÇÃÖ¤­´¹¤¨¤¿¤è¤¦¤Ê¼°¤òɾ²Á¤¹¤ë5¡¤¤È¤¤¤¦¤³¤È ¤Ï³Ø¤ó¤À¤¬¡¤square(square(2)) ¤Î¤è¤¦¤Ê¼°¤Î¡¤Æó¤Ä¤¢¤ë´Ø¿ôŬÍѤΤ¦¤Á¡¤ ¤É¤Á¤é¤òÀè¤Ëɾ²Á¤¹¤ë¤«¡¤¤È¤¤¤Ã¤¿¡Ö¤É¤Î¤è¤¦¤Ê½çÈ֤ǡ×ÃͤËɾ²Á¤µ¤ì¤ë¤« ¤Ë¤Ä¤¤¤Æ¤ÏÀâÌÀ¤·¤Æ¤³¤Ê¤«¤Ã¤¿¡¥ ¤½¤Î¤Ò¤È¤Ä¤ÎÍýͳ¤Ï¡¤ ºÆµ¢´Ø¿ô¤òƳÆþ¤¹¤ë¤Þ¤Ç¤Ë¤Õ¤ì¤¿¼°¤Ë¤Ä¤¤¤Æ¤Ï¡¤É¾²ÁÊýË¡¤Ë´Ø¤ï¤é¤º Ãͤ¬ÊѤé¤Ê¤«¤Ã¤¿¤«¤é¤Ç¤¢¤ë¡¥ ¤³¤Î¤è¤¦¤ÊÉôʬ¼°¤Îɾ²Á½ç½ø¤òɾ²ÁÀïά(evaluation strategy)¤È¤¤¤¦¡¥ ¤³¤³¤Ç¤¹¤³¤·´ó¤êÆ»¤ò¤·¤Æ¡¤¤¤¤í¤¤¤í¤Êɾ²ÁÀïά¤ò¤ß¤Æ¤¤¤³¤¦¡¥

ºÇ¤âñ½ã¤«¤Ä¿Í´Ö¤¬»æ¤Î¾å¤Ç·×»»¤¹¤ë¾ì¹ç¤È¶á¤¤¤Î¤¬¡¤ ¡Ö´Ø¿ô¤òŬÍѤ¹¤ë¤È¤­¤Ë¤Ï¤Þ¤º°ú¿ô¤òÃͤËɾ²Á¤¹¤ë¡×¤È¤¤¤¦ Ã͸ƽФ·(call-by-value)¤ÎÀïά¤Ç¤¢¤ë¡¥ Î㤨¤Ð¡¤¾å¤Î¼°¤Ï square ¤ÎÄêµÁ¤ò
# let square x = x * x;;
val square : int -> int = <fun>
¤È¤¹¤ë¤È¡¤
square(square(2)) square(2 * 2)
  square(4)
  4 * 4
  16
¤È¤¤¤¦¤è¤¦¤Ë¡¤¤Þ¤º¡¤³°Â¦¤Î square ¤Î°ú¿ô¤Ç¤¢¤ë square(2) ¤Îɾ²Á¤ò ¹Ô¤Ã¤Æ¤¤¤ë¡¥Objective Caml ¤ò´Þ¤à¿¤¯¤Î¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Ç¤Ï¡¤Ã͸ƽФ·¤¬»È¤ï¤ì¤Æ¤¤ ¤ë¡¥

¼¡¤ËºÆµ¢¤òȼ¤¦É¾²Á¤Ë¤Ä¤¤¤Æ¸«¤Æ¤ß¤è¤¦¡¥fact 4 ¤Ï¡¤°Ê²¼¤Î¤è¤¦¤Ê¼ê½ç¤Ç ɾ²Á¤µ¤ì¤ë¡¥
fact 4 if 4 = 1 then 1 else 4 * fact(4-1)
  4 * fact (4 - 1)
  4 * fact 3
  → ⋯ → 4 * (3 * fact (3-1))
  → ⋯ → 4 * (3 * fact 2)
  → ⋯ → 4 * (3 * (2 * fact (2-1)))
  → ⋯ → 4 * (3 * (2 * fact 1))
  → ⋯ → 4 * (3 * (2 * 1))
  → ⋯ → 4 * (3 * 2)
  → ⋯ → 4 * 6
  → ⋯ → 24

Ã͸ƽФ·¤Ïľ´ÑŪ¤Ç¿¤¯¤Î¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Ç»È¤ï¤ì¤Æ¤¤¤ë¤â¤Î¤Î¡¤Í¾·×¤Ê ·×»»¤ò¹Ô¤Ã¤Æ¤·¤Þ¤¦¤³¤È¤¬¤¢¤ë¤È¤¤¤¦·çÅÀ¤¬¤¢¤ë¡¥Î㤨¤Ð¡¤(¤ä¤ä¿Í¹©Åª¤ÊÎ㠤Ǥ¢¤ë¤¬)
# let zero (x : int) = 0;;
val zero : int -> int = <fun>
¤Î¤è¤¦¤Ê´Ø¿ô¤Ï¡¤°ú¿ô¤¬¤É¤ó¤ÊÀ°¿ô¤Ç¤¢¤í¤¦¤È¤â¡¤0¤òÊÖ¤¹¤Ë¤â´Ø¤ï¤é¤º¡¤ zero(square(square(2))) ¤Î¤è¤¦¤Ê¼°¤Îɾ²Á¤ÎºÝ¡¤°ú¿ô¤ò·×»»¤·¤Æ¤·¤Þ¤¦¡¥ ¤Þ¤¿¡¤Ã͸ƤӽФ·¤Î¸À¸ì¤Ç¤Ï¡¤¾ò·ïʬ´ô¤ò´Ø¿ô¤Çɽ¸½¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤(Îý ½¬ÌäÂ껲¾È)¡¥

¤³¤Î·çÅÀ¤Ï¡¤¤È¤Ë¤«¤¯°ú¿ô¤òÀè¤Ëɾ²Á¤·¤Æ¤¤¤¯¤³¤È(¤³¤ÎÀ­¼Á¤ò eagerness, strictness ¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë)¤Ëµ¯°ø¤¹¤ë¡¥¤³¤ì¤ËÂФ·¤Æ¡¤¤¤¤Þ¤«¤é½Ò¤Ù¤ë ¤Õ¤¿¤Ä¤ÎÀïά¤Ï¡¤lazy ¤Êɾ²Á¤È¸Æ¤Ð¤ì¡¤¡Ö°ú¿ô¤Ï»È¤¦¤Þ¤Çɾ²Á¤·¤Ê¤¤¡×Àïά¤Ç¤¢¤ë¡¥

¤Þ¤º¡¤lazy ¤ÊÀïά¤Î¤Ò¤È¤Ä¤á¤¬¡¤¡Ö³°Â¦¤Î´Ø¿ôŬÍѤ«¤é¡¤°ú¿ô¤ò¼°¤Î¤Þ¤Þ¥Ñ¥é¥á¡¼ ¥¿¤ËÃÖ´¹¤¹¤ë¡×̾Á°¸Æ½Ð¤·(call-by-name)¤Ç¤¢¤ë¡¥¤³¤ÎÀïά¤Î²¼¤Ç¤Ï¡¤ Àè¤Û¤É¤Î square(square(2)) ¤ª¤è¤Ó¡¤zero(square(square(2))) ¤Ï¡¤¤½¤ì¤¾¤ì¡¤
square(square(2)) square(2) * square(2)
  (2 * 2) * square(2)
  4 * square(2)
  4 * (2 * 2)
  4 * 4
  16
zero(square(square(2))) 0
¤Î¤è¤¦¤Ëɾ²Á¤µ¤ì¤ë¡¥¤¿¤·¤«¤Ë°ú¿ô¤ò»È¤ï¤Ê¤¤´Ø¿ô¤Îɾ²Á¤Ë¤ª¤¤¤Æ¤Ï̵Â̤¬ ¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¤¬¤ï¤«¤ë¡¥¤½¤ÎÂå¤ï¤ê¤Ë¡¤·×»»¼°¤ò¤½¤Î¤Þ¤Þ¥³¥Ô¡¼¤·¤Æ¤·¤Þ¤¦ ¤¿¤á¤Ë¡¤Éôʬ¼° square(2) ¤Î·×»»¤¬ÆóÅÙȯÀ¸¤·¤Æ¤¤¤ë¡¥

¤³¤Î·çÅÀ¤ò¤Ê¤¯¤·¤¿¤â¤Î¤¬¡¤É¬Í׸ƽФ·(call-by-need)¤ÎÀïά¤Ç¤¢ ¤ë¡¥¤³¤ì¤Ï¡¤¡Ö³°Â¦¤Î´Ø¿ôŬÍѤ«¤é¡¤°ú¿ô¤ò¼°¤Î¤Þ¤Þ¥Ñ¥é¥á¡¼ ¥¿¤ËÃÖ´¹¤¹¤ë¤¬¡¤°ìÅÙɾ²Á¤·¤¿¼°¤Ï¡¤·ë²Ì¤ò³Ð¤¨¤Æ¤ª¤¤¤ÆÆóÅÙɾ²Á¤·¤Ê¤¤¡×¤â¤Î¤Ç¡¤ ¥Ñ¥é¥á¡¼¥¿¤ò°ú¿ô¤ÇÃÖ´¹¤¹¤ëÂå¤ê¤Ë¡¤°ú¿ô¼°¤Î¶¦Í­´Ø·¸¤ò¼¨¤·¤¿¤è¤¦ ¤Ê¥°¥é¥Õ¤Ç¹Í¤¨¤ë¤È¤ï¤«¤ê¤ä¤¹¤¤¡¥
square(square(2))   →   * /^/[d] /_/[d]
square(2)
  →   * /^/[d] /_/[d]
* /^/[d] /_/[d]
2
  →   * /^/[d] /_/[d]
4
  →   16

call-by-need ¤Çɾ²Á¤¬¹Ô¤ï¤ì¤ë¸À¸ì¤Ë¤Ï Haskell, Miranda ¤Ê¤É¤¬¤¢¤ê¡¤¤¤¤º¤ì¤â ´Ø¿ô·¿¸À¸ì¤Ç¤¢¤ë¡¥lazy ¤Ê¸À¸ì¤Ë¤Ï̵¸Â¤ÎÂ礭¤µ¤ò»ý¤Ä¹½Â¤¤Ê¤É¤ò¤­¤ì¤¤¤Ëɽ¸½¤Ç ¤­¤ë¤Ê¤É¤ÎÍøÅÀ¤¬¤¢¤ë¤¬¡¤Éôʬ¼°¤¬¤¤¤Äɾ²Á¤µ¤ì¤ë¤«¤ï¤«¤ê¤Ë¤¯¤¤¤¿¤á¡¤ÉûºîÍÑ¤È ¤ÎÁêÀ­¤¬°­¤¤¡¥¼ÂºÝ¤³¤ì¤é¤Î¸À¸ì¤Ç¤ÏÉûºîÍѤòȼ¤¦µ¡Ç½¤¬¤Ê¤¤¡¥¤Þ¤¿ ¼ÂÁõ¤â call-by-value ¸À¸ì¤ËÈæ¤ÙÊ£»¨¤Ç¤¢¤ë¡¥(¾å¤Ë¼¨¤·¤¿¤è¤¦¤Ê ¥°¥é¥Õ¤Î½ñ¤­´¹¤¨¤ËÁêÅö¤¹¤ë graph reduction ¤È¤¤¤¦µ»½Ñ¤¬¤è¤¯ ÍѤ¤¤é¤ì¤Æ¤¤¤ë¡¥)

3.3.3 ËöÈøºÆµ¢¤È·«¤êÊÖ¤·

¾å¤ÇÄêµÁ¤·¤¿ fact ´Ø¿ô¤Îɾ²Á¤ÎÍͻҤò¤ß¤ë¤È¤ï¤«¤ë¤è¤¦¤Ë¡¤ ·×»»ÅÓÃæ¤Ç¡Ö¤¢¤È¤Ç·×»»¤µ¤ì¤ëÉôʬ¡×¤Ç¤¢¤ë 4 * (3 * (...)) ¤È¤¤¤Ã¤¿¤â¤Î¤òµ­²±¤·¤Æ¤ª¤«¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥n ¤¬Â礭¤¯¤Ê¤ë¤È ¤³¤Î¼°¤ÎÂ礭¤µ¤âÂ礭¤¯¤Ê¤ê¡¤É¾²Á¤ËɬÍפʶõ´Ö»ÈÍÑÎ̤¬Â礭¤¯ ¤Ê¤Ã¤Æ¤·¤Þ¤¦¡¥¤È¤³¤í¤¬¾è»»¤Ë´Ø¤·¤Æ¤Ï·ë¹ç§¤«¤é¡¤ n ⋅ ((n-1) ⋅ (n-2)!) = (n ⋅ (n-1)) ⋅ (n-2)! ¤¬À®Î©¤¹¤ë¤¿¤á (n-2)! ¤Î·×»»¤Ë¤È¤ê¤«¤«¤ëÁ°¤Ë¡¤n ⋅ (n-1) ¤òÀè¤Ë ·×»»¤¹¤ë¤³¤È¤Ç¡¤¡Ö¤¢¤È¤Ç·×»»¤¹¤ëÉôʬ¡×¤ÎÂ礭¤µ¤ò¾®¤µ¤¯ÊݤĤ³¤È¤¬²Äǽ¤Ç¤¢¤ë¡¥ ¤³¤Î¤è¤¦¤Ê¹©Éפò¥×¥í¥°¥é¥à¤¹¤ë¤³¤È¤ò¹Í¤¨¤ë¤È¡¤°ú¿ô n ¤Î¾ðÊó°Ê³°¤Ë¡¤ Àè¤Ë·×»»¤¹¤ë¤Ù¤­¼°¤Î¾ðÊó¤¬É¬ÍפǤ¢¤ê¡¤
# let rec facti (res, n) = (* iterative version of fact *)
#   if n = 1 then res (* equal to res * 1 *) 
#   else facti (res * n, n - 1);;
val facti : int * int -> int = <fun>
¤Î¤è¤¦¤ÊÄêµÁ¤Ë¤Ê¤ë¡¥°ú¿ô res ¤¬¡¤fact ¤ÇȯÀ¸¤·¤Æ¤¤¤¿ ºÆµ¢¸Æ½Ð¤·¤Î³°Â¦¤Î¾è»»¼°¤ÎÃͤËÂбþ¤¹¤ë¡¥¤³¤Î´Ø¿ô¤Ï¡¤ Àµ³Î¤Ë¤Ï¡¤facti (n,m) ¤Ç¡¤nm! ¤ò·×»»¤¹¤ë¡¥
# facti (1, 4);;
- : int = 24
°Ê²¼¤Ë¡¤facti (1, 4) ¤Îɾ²Á¤ÎÍͻҤò¼¨¤¹¡¥
facti (1, 4) if 4 = 1 then 1 else facti(1 * 4, 4 - 1)
  facti (4, 3)
  if 3 = 1 then 4 else facti(4 * 3, 3 - 1)
  facti (12, 2)
  if 2 = 1 then 12 else facti(12 * 2, 2 - 1)
  facti (24, 1)
  if 1 = 1 then 24 else facti(24 * 1, 1 - 1)
  24
fact 4 ¤È°ã¤¤¡¤·×»»¤ÎÅÓÃæ·Ð²á¤Î¼°¤¬¾®¤µ¤¤(°ú¿ô¤ÎÂ礭¤µ¤Ë°Í¸¤·¤Ê¤¤)¤³¤È¤¬ ¤ï¤«¤ë¤À¤í¤¦¡¥¤³¤Î¤è¤¦¤ÊÄêµÁ¤ò¡¤È¿ÉüŪ(iterative)¤Ç¤¢¤ë¡¤¤â¤·¤¯¤Ï ºÆµ¢¸Æ½Ð¤·¤¬ËÜÂÎÃæ¤Î·×»»¤Î°ìÈֺǸå¤Ë¤¢¤ë¤³¤È¤«¤é¡¤ËöÈøºÆµ¢Åª(tail-recursive)¤Ç¤¢¤ë¡¤¤È¤¤¤¦¡¥°ìÈ̤ˤϺƵ¢´Ø¿ô¤ÏºÆµ¢¤¬¿¼¤¯¤Ê¤ë¤Ë¤Ä¤ì¡¤ ¥á¥â¥ê¤Î»ÈÍÑÎ̤¬ÁýÂ礹¤ë¤¬¡¤¸­¤¤¥³¥ó¥Ñ¥¤¥é¤ÏËöÈøºÆµ¢´Ø¿ô¤ò (¼«Æ°Åª¤Ë)ÆÃÊÌ°·¤¤¤·¤Æ¡¤¥á¥â¥ê¤Î»ÈÍÑÎ̤¬ºÆµ¢¤Î¿¼¤µ¤Ë´Ø¤ï¤é¤º¸ÇÄêÎ̤Ǥ¢¤ë¤è ¤¦¤Ê¥³¡¼¥É¤òÀ¸À®¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥¤·¤«¤·¡¤¤É¤ó¤ÊºÆµ¢´Ø¿ô¤âÈ¿ÉüŪ¤Ë ÄêµÁ¤¹¤ì¤Ð¤è¤¤¤È¤¤¤¦¤ï¤±¤Ç¤â¤Ê¤¤¡¥¼ÂºÝ¡¤ÁÇËѤʺƵ¢ÅªÄêµÁ ¤òÈ¿ÉüŪ¤Ë¤¹¤ë¤È°ú¿ô¤Î¿ô¤¬¤Ò¤È¤ÄÁý¤¨¡¤¤½¤ì¤Ëȼ¤Ã¤ÆÄêµÁ¤Î¤ï¤«¤ê¤ä¤¹¤µ¤¬ ¤«¤Ê¤ê¸º¾¯¤¹¤ë¡¥

¤³¤³¤Ç¤Ï facti ¤ò¥È¥Ã¥×¥ì¥Ù¥ë¤Î´Ø¿ô¤È¤·¤ÆÀë¸À¤·¤¿¤¬¡¤¤³¤ì¤Ï¤¤¤ï¤Ð Êä½õŪ¤Ê´Ø¿ô¤Ç¤¢¤ë¡¥Âè1°ú¿ô¤ò1°Ê³° ¤Ç¤è¤ÖɬÍפ¬¤Ê¤¤¾ì¹ç¤Ï¡¤facti ¤ò¸íÍѤµ¤ì¤Ê¤¤¤è¤¦¤Ë¡¤
# let fact n = (* facti is localized *)
#   let rec facti (res, n) = 
#     if n = 1 then res else facti (res * n, n - 1) 
#   in facti (1, n);;
val fact : int -> int = <fun>
¤Î¤è¤¦¤Ë¡¤¶É½êŪ¤ËÀë¸À¤¹¤ë¤«¡¤
# let rec fact (res, n) = if n = 1 then res else fact (res * n, n - 1);;
val fact : int * int -> int = <fun>
# let fact n = fact (1, n);;
val fact : int -> int = <fun>
Ʊ¤¸Ì¾Á°¤Î´Ø¿ô¤òÀë¸À¤¹¤ë¤³¤È¤Ç±£¤¹¤Î¤¬¡¤Objective Caml¥×¥í¥°¥é¥ß¥ó¥°¤Î¾ïÅå ¥Æ¥¯¥Ë¥Ã¥¯¤È¤·¤Æ»È¤ï¤ì¤ë¡¥

3.3.4 ¤è¤êÊ£»¨¤ÊºÆµ¢

¤³¤ì¤Þ¤Ç¤ËÅо줷¤¿ºÆµ¢´Ø¿ô¤ÏºÆµ¢¸Æ½Ð¤·¤ò¹Ô¤¦¾ì½ê¤¬¤»¤¤¤¼¤¤1¸Ä½ê¤·¤«¤Ê¤«¤Ã¤¿¡¥ ¤³¤Î¤è¤¦¤ÊºÆµ¢¤Î»ÅÊý¤òÀþ·ÁºÆµ¢¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡¥¤³¤³¤Ç¤ÏºÆµ¢¸Æ½Ð¤·¤¬ 2¸Ä½ê°Ê¾å¤Ç¹Ô¤ï¤ì¤ë¤è¤¦¤ÊºÆµ¢´Ø¿ô¤ò¤¤¤¯¤Ä¤«¤ß¤Æ¤¤¤¯¡¥

¥Õ¥£¥Ü¥Ê¥Ã¥Á¿ô
¥Õ¥£¥Ü¥Ê¥Ã¥Á¿ôÎó Fi¤Ï°Ê²¼¤ÎÁ²²½¼°¤òËþ¤¿¤¹¤è¤¦¤Ê¿ôÎó¤Ç¤¢¤ë¡¥
F1 = 1
F2 = 1
Fn = Fn-1 + Fn-2
n ÈÖÌܤΥե£¥Ü¥Ê¥Ã¥Á¿ô¤òµá¤á¤ë´Ø¿ô¤Ï¡¤
# let rec fib n = (* nth Fibonacci number *)
#   if n = 1 || n = 2 then 1 else fib(n - 1) + fib(n - 2);;
val fib : int -> int = <fun>
¤È¤·¤ÆÀë¸À¤Ç¤­¤ë¡¥elseÀá¤ËºÆµ¢¸Æ½Ð¤·¤¬2¸Ä½ê¸½¤ì¤Æ¤¤¤ë¡¥

¤·¤«¤·¡¤¤³¤ÎÄêµÁ¤Ï¡¤Fn ¤Î·×»»¤ËFn-2¤Î·×»»¤¬ ÆóÅÙȯÀ¸¤¹¤ë¤Ê¤É¡¤Èó¾ï¤Ë¿¤¯¤ÎºÆµ¢¸Æ½Ð¤·¤òȼ¤¦¤¿¤á¤Ë¸úΨŪ¤Ç¤Ï¤Ê¤¤¡¥ (fib 30 ¤Îɾ²Á¤ò»î¤·¤Æ¤ß¤è¡¥)¤³¤ì¤ò²þÁ±¤·¤¿¤Î¤¬¡¤¼¡¤ÎÄêµÁ¤Ç¤¢¤ë¡¥
# let rec fib_pair n = 
#   if n = 1 then (0, 1)
#   else 
#     let (prev, curr) = fib_pair (n - 1) in (curr, curr + prev);;
val fib_pair : int -> int * int = <fun>
¤³¤ÎÄêµÁ¤Ç¤Ï¡¤n ¤«¤é Fn ¤È¤È¤â¤Ë Fn-1 ¤â ·×»»¤¹¤ë¡¥¤Þ¤¿¡¤Àþ·ÁºÆµ¢¤ÊÄêµÁ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¤ËÃí°Õ¡¥

Euclid ¤Î¸ß½üË¡
Euclid ¤Î¸ß½üË¡¤Ï¡¤¼«Á³¿ô m ¤È n (¤¿¤À¤· m < n) ¤ÎºÇÂç¸øÌó¿ô¤Ï¡¤n ÷ m ¤Î¾ê;¤È m ¤ÎºÇÂç¸øÌó¿ô¤Ë Åù¤·¤¤À­¼Á¤òÍѤ¤¤Æ¡¤ÆóÀ°¿ô¤ÎºÇÂç¸øÌó¿ô¤òµá¤á¤ëÊýË¡¤Ç¤¢¤ë¡¥

ÁȤ߹ç¤ï¤»¿ô
n ¸Ä¤Î¤â¤Î¤Î¤Ê¤«¤«¤é m ¸Ä¤Î¤â¤Î¤òÁª¤Ó¤À¤¹Áȹç¤ï¤»¤Î¾ì¹ç¤Î¿ô
æ
è
n
m
ö
ø
¤Ï¡¤
æ
è
n
m
ö
ø
=
n × ⋯ × (n-m+1)
m × ⋯ × 1
¤ÇÄêµÁ¤µ¤ì¤ë¡¥¤³¤ì¤òºÆµ¢Åª¤Ë
æ
è
n
0
ö
ø
= 1
æ
è
n
n
ö
ø
= 1
æ
è
n
m
ö
ø
=
æ
è
n-1
m
ö
ø
+ æ
è
n-1
m-1
ö
ø
    ¤¿¤À¤· 0 ≤ mn
¤ÈÄêµÁ¤¹¤ë¤³¤È¤â¤Ç¤­¤ë¡¥

3.3.5 Áê¸ßºÆµ¢

ºÇ¸å¤Ë¡¤Æó¤Ä°Ê¾å¤Î´Ø¿ô¤¬¤ª¸ß¤¤¤ò¸Æ¤Ó¹ç¤¦Áê¸ßºÆµ¢(mutual recursion)¤ò¤ß¤ë¡¥Áê¸ßºÆµ¢´Ø¿ô¤Ï¡¤°ìÈÌŪ¤Ë
let rec f1 ⟨ ¥Ñ¥¿¡¼¥ó1 ⟩ = e1
and f2 ⟨ ¥Ñ¥¿¡¼¥ó2 ⟩ = e2
  ⋮
and fn ⟨ ¥Ñ¥¿¡¼¥ón ⟩ = en
¤È¤¤¤¦·Á¤ÇÄêµÁ¤µ¤ì¤ë¡¥³ÆËÜÂΤμ° ei ¤Ë¤Ï¼«Ê¬¼«¿È¤Ç¤¢¤ë fi ¤À¤±¤Ç¤Ê¤¯Æ±»þ¤ËÄêµÁ¤µ¤ì¤ë f1, ..., fn Á´¤Æ¤ò¸Æ¤Ö¤³¤È¤¬¤Ç¤­¤ë¡¥

Èó¾ï¤ËÇϼ¯Çϼ¯¤·¤¤Îã¤Ç¤Ï¤¢¤ë¤¬¡¤¼¡¤Î´Ø¿ô even, odd ¤Ï ¤È¤¤¤¦ºÆµ¢Åª¤ÊÄêµÁ¤Ë´ð¤Å¤­¡¤Í¿¤¨¤é¤ì¤¿Àµ¤ÎÀ°¿ô¤¬¶ö¿ô¤«´ñ¿ô¤«È½Äꤹ¤ë´Ø¿ô¤Ç ¤¢¤ë¡¥
# let rec even n = (* works for positive integers *)
#   if n = 0 then true else
#   if n = 1 then false else odd(n - 1)
# and odd n = 
#   if n = 0 then false else
#   if n = 1 then true else even(n - 1);;
val even : int -> bool = <fun>
val odd : int -> bool = <fun>
# even 6;;
- : bool = true
# odd 14;;
- : bool = false
¤â¤¦¾¯¤·¡¤¸½¼ÂŪ¤ÊÎã¤È¤·¤Æ¡¤arctan1 ¤ÎŸ³«·Á
π
4
= 1 -
1
3
+
1
5
-
1
7
⋯ +
1
4k+1
-
1
4k+3
¤ò¹Í¤¨¤ë¡¥ÅÓÃæ¤Þ¤Ç¤ÎϤòµá¤á¤ë´Ø¿ô¤Ï¡¤Àµ¤Î¹à¤ò­¤¹´Ø¿ô¤È Éé¤Î¹à¤ò­¤¹´Ø¿ô¤òÁê¸ßºÆµ¢Åª¤ËÄêµÁ¤Ç¤­¤ë¡¥
# let rec pos n = 
#   neg (n-1) +. 1.0 /. (float_of_int (4 * n + 1))
# and neg n = 
#   if n < 0 then 0.0
#   else pos n -. 1.0 /. (float_of_int (4 * n + 3));;
val pos : int -> float = <fun>
val neg : int -> float = <fun>
# 4.0 *. pos 200;;
- : float = 3.1440864153
# 4.0 *. pos 800;;
- : float = 3.14221726315
¤æ¤Ã¤¯¤ê¤È π/4 ¤Ë¼ý«¤·¤Æ¹Ô¤¯¡¥

3.3.6 Îý½¬ÌäÂê

Exercise 7  x ¤Ï¼Â¿ô¡¤n ¤Ï 0 °Ê¾å¤ÎÀ°¿ô¤È¤·¤Æ¡¤ xn ¤ò·×»»¤¹¤ë´Ø¿ô pow (x,n) ¤ò°Ê²¼¤Î2¼ïÎàÄêµÁ¤»¤è¡¥
  1. pow ¤Î(ºÆµ¢)¸Æ½Ð¤·¤ò n ²óȼ¤¦ÄêµÁ
  2. pow ¤Î(ºÆµ¢)¸Æ½Ð¤·¤ÏÌó log2 n ²ó¤Ç¤¹¤àÄêµÁ¡¥ (¥Ò¥ó¥È: x2n = (x2)n ¤Ç¤¢¤ë¡¥¤Ç¤Ï¡¤x2n+1 = ?)

Exercise 8  Á°Ìä¤Î pow ¤ÎºÇ½é¤ÎÄêµÁ¤òÈ¿ÉüŪ¤Ë¤·¤¿ powi ¤òÄêµÁ¤»¤è¡¥ (¤â¤Á¤í¤ó°ú¿ô¤Î¿ô¤Ï°ì¤ÄÁý¤¨¤ë¡¥¸Æ½Ð¤·Êý¤âÀâÌÀ¤»¤è¡¥)

Exercise 9  if ¼°¤Ï Objective Caml ¤Î´Ø¿ô¤Çɽ¸½¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡¥°Ê²¼¤Î´Ø¿ô¤Ï ¤½¤ì¤ò»î¤ß¤¿¤â¤Î¤Ç¤¢¤ë¡¥fact 4 ¤Î·×»»¤Îɾ²Á¥¹¥Æ¥Ã¥×¤ò¹Í¤¨¡¤ ¤Ê¤¼¤¦¤Þ¤¯·×»»¤Ç¤­¤Ê¤¤¤Î¤«ÀâÌÀ¤»¤è¡¥

# let cond (b, e1, e2) : int = if b then e1 else e2;;
val cond : bool * int * int -> int = <fun>
# let rec fact n = cond ((n = 1), 1, n * fact (n-1));;
val fact : int -> int = <fun>

# fact 4;;
????

Exercise 10  fib 4 ¤ÎÃ͸ƽФ·¤Ë¤è¤ëɾ²Á¥¹¥Æ¥Ã¥×¤ò¥Æ¥­¥¹¥È¤ËÊï¤Ã¤Æ¼¨¤»¡¥

Exercise 11  °Ê²¼¤Î´Ø¿ô¤òÄêµÁ¤»¤è¡¥
  1. Euclid ¤Î¸ß½üË¡¤ÇÆóÀ°¿ô¤ÎºÇÂç¸øÌó¿ô¤òµá¤á¤ë´Ø¿ô gcd¡¥
  2. ¥Æ¥­¥¹¥È¤ÎºÆµ¢Åª¤ÊÄêµÁ¤Ç
    æ
    è
    n
    m
    ö
    ø
    ¤òµá¤á¤ë´Ø¿ô comb¡¥
  3. fib_pair ¤òÈ¿ÉüŪ¤Ë½ñ¤­Ä¾¤·¤¿ fib_iter¡¥
  4. Í¿¤¨¤é¤ì¤¿Ê¸»úÎó¤Î¤Ê¤«¤Ç ASCII ¥³¡¼¥É¤¬ºÇ¤âÂ礭¤¤Ê¸»ú¤òÊÖ¤¹ max_ascii ´Ø¿ô¡¥(ʸ»úÎ󤫤éʸ»ú¤ò¼è½Ð¤¹ÊýË¡¤Ï 2.2.5 Àá¤ò»²¾È¤Î¤³¤È¡¥)

Exercise 12  neg ¤òñÆȤÇÍѤ¤¤ëɬÍפ¬¤Ê¤±¤ì¤Ð¡¤pos ¤È neg ¤Ï°ì¤Ä¤Î´Ø¿ô¤Ë ¤Þ¤È¤á¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥°ì¤Ä¤Ë¤Þ¤È¤á¤ÆÄêµÁ¤»¤è¡¥


1
ºÇ¸å¤Î¡ÖÉÔÌÀ¤À¤Ã¤¿Éôʬ¤ò retrieve ¤¹¤ë¡×¤È¤¤¤¦¤Î¤Ï¼ª´·¤ì¤Ê¤¤¤«¤â¤·¤ì¤Ê¤¤¤¬¡¤UNIX ¤Î egrep ¥³¥Þ¥ó¥É¤Ç¤Ï¡¤() ¤Ç¥Þ¥Ã¥Á¤·¤¿Ê¸»úÎó¤ËÈÖ¹æ¤ò¤Ä¤±Æ±¤¸¥Ñ¥¿¡¼¥ó¼°¤ÎÃæ¤Ç \ 1 ¤Ê¤É¤È¤·¤Æ»²¾È¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥
2
¤¬¡¤¤³¤ÎÄêµÁ¤Î¾ì¹ç pair ¤¬Â¾¤Î¾ì½ê¤Ç»È¤ï¤ì¤Æ¤¤¤Ê¤¤¤Î¤ÇºÇ½é¤ÎÄêµÁ¤Î´Ê·é¤µ¤Ë¾¡¤ë¥á¥ê¥Ã¥È¤Ï¤Ê¤¤¤À¤í¤¦
3
0! = 1 ¤ÈÄêµÁ¤¹¤ë¤³¤È¤â¤¢¤ë¡¥
4
¸½ºß¤Î Objective Caml ¤Î¼ÂÁõ¤Ç¤Ï¡¤´Ø¿ô°Ê³°¤Î¤â¤Î¤Ç ºÆµ¢Åª¤ËÄêµÁ¤Ç¤­¤ë¼°¤¬¤¢¤ë¤¬¤³¤³¤Ç¤Ï°·¤ï¤Ê¤¤¡¥
5
¤¹¤Ç¤Ë¸« ¤¿¤è¤¦¤Ë¥Ñ¥é¥á¡¼¥¿¤ÎÃÖ´¹¤Ï´Ä¶­¤Î»ÅÁȤߤǼ¸½¤µ¤ì¤Æ¤¤¤ë¤¬¡¤¤³¤ÎÀá¤Ç¤Ï ¤è¤êñ½ã¤«¤Äľ´ÑŪ¤ÊÃÖ¤­´¹¤¨¥â¥Ç¥ë¤ò»È¤Ã¤ÆÀâÌÀ¤ò¹Ô¤¦¡¥

Previous Up Next