Function ในแบบ Haskell

Function ในแบบ Haskell เป็นยังไง
Haskell เป็น Functional Programming Language เป็นการเขียนโปรแกรมโดยอาศัยการสร้าง Function ที่เหมือนกับการกำหนด Function ในทางคณิตศาสตร์ นั่นคือการออกแบบความสัมพันธ์ของข้อมูลประเภทหนึ่งที่เป็น Input ไปหาข้อมูลอีกประเภทหนึ่งที่เป็น Output ตัวอย่างเช่น
double x = x * 2
โค้ดที่เห็น เป็นการกำหนด Function ชื่อ double โดยเรากำหนด x แทน Input และความสัมพันธ์ของ Input และ Output ของ Function นี้คือ Output เท่ากับ Input คูณกับ 2
แม้จะเขียนอยู่ในรูปของสมการ แต่เราก็บอกเป็นความสัมพันธ์ได้คือ double เป็น Function ที่ Input เป็นเซตของจำนวนที่สามารถเอามาคูณกับ 2 ได้ เช่น จำนวนเต็ม, จำนวนจริง ส่วน String ไม่สามารถเอามาคูณกับ 2 ได้เลยไม่ได้เป็นสมาชิกของเซตของ Input ของ Function double
Type ของ Function
Type ของ Function ใน Haskell เป็นการบอกว่า Function นั้นมี Input เป็นเซตของค่าที่เป็นไปได้อะไรบ้าง และมี Output เป็นเซตของค่าที่เป็นไปได้อะไรบ้าง จากตัวอย่างด้านบน เราไม่ได้มีอะไรบอกว่า double มี Type เป็นอะไร แต่ Haskell มีกลไกที่เรียกว่า Type Inferrence เพื่อค้นหาได้เองว่า Type ที่เป็นไปได้ของ Function คืออะไร อย่าง double นั้นเมื่อใช้ คำสั่ง :t double ที่ ghci เราจะเห็น type ออกมาแบบนี้
double :: Num a => a -> a
ตรง Num a คือการกำหนดเงื่อนไข Type Class เราอาจจะยังไม่เข้าใจตอนนี้ว่าคืออะไร แต่มันคือการบอกว่า a คือสมาชิกของ Type อะไรก็ได้ที่เป็นตัวเลขนั่นละครับ
ส่วนตรง a -> a เป็นการบอกว่า Input ที่เป็นไปได้ของ double ก็คือเซตของ Type a และ Output ที่เป็นไปได้ของ double คือ Type a เช่นกัน
ทีนี้ถ้าเราอยากระบุลงไปเองว่าเซตของ Input และ Output คืออะไรสามารถกำหนดได้แบบนี้
double :: Int -> Int
double x = x * 2
ตัวอย่างนี้คือกำหนดให้เซตของ Input ที่เป็นไปได้คือค่าแบบจำนวนเต็ม และ Output คือจำนวนเต็ม เช่นกัน
Pattern Matching
ถ้าย้อนไปดูโพสเรื่อง Function ในทางคณิตศาสตร์ อีกรอบ จะเห็นว่าผมใช้รูปแล้วโยงเส้นจาก Input ไปหา Output แต่ตัวอย่าง double ข้างบนนิยามโดยใช้ ตัวแปร และสมการแทนความสัมพันธ์ของ Input และ Output แต่ใน Haskell เราสามารถสร้างความสัมพันธ์ของ Input และ Output โดยใช้ข้อมูลจริงๆได้เลยเช่น
double 1 = 2
double 2 = 4
double 3 = 6
double 4 = 8
เมื่อมีการเอา Function นี้ไปใช้งาน Haskell จะค้นหาให้เองว่า Input ที่กำหนดมีนิยามเอาไว้หรือไม่ และสัมพันธ์กับ Output อะไรเช่นเรียก double 2 ใน ghci จะได้ค่า 4 วิธีการค้นหาแบบนี้เรียกว่า Pattern Matching ถ้า Haskell ไม่สามารถ Matching ได้จะเกิด Exception ขึ้นมา
จากตัวอย่างขึ้นบน ถ้าเราเรียก double 5 จะทำให้เกิด Exception ดังนั้นจะเห็นว่า เรามักจะใช้ตัวแปรแทนการระบุค่าตรงๆเพราะจะทำให้ Matching ค่าได้ครอบคลุมทุกค่าของ Input ที่เป็นไปได้
สรุป
นั่นคือวิธีสร้าง Function ใน Haskell แบบง่ายๆ แต่ก็ยกตัวอย่างให้ดูเพื่อให้นึกเสมอว่า Function ของ Haskell นั้นยึดโยงกับการคิดแบบเดียวกันกับ Function ในทางคณิตศาสตร์ ไม่เหมือนกันกับ Function ในหลายๆภาษาที่เป็นแบบ Imperative หรือ Object Oriented ที่ Function เป็นการนิยาม ลำดับขั้นตอนการทำงาน และ ด้วยวิธีคิดแบบนี้ ทำให้ Haskell ไม่มีเรื่องตัวแปรแบบ Mutable เพราะการนิยาม Function ไม่เกี่ยวกับการพูดถึงวิธีการเก็บข้อมูล จึงไม่จำเป็นต้องมีการเปลี่ยนแปลงข้อมูลของตัวแปรนั่นเอง