December 7, 2012

Haskell: ฟังก์ชันและขอบเขตของตัวแปร

นอกจากเราจะสร้างฟังก์ชันด้วย if-else แล้ว Haskell ยังมีความสามารถในการทำ pattern matching กับตัวแปรฟังก์ชันได้อีกด้วย

ตัวอย่างฟังก์ชันจากคราวก่อนในแบบ pattern matching


pattern matching จะช่วยให้อ่านฟังก์ชันที่อยู่ในรูป recursive ง่ายขึ้นมาก


แต่ฟังก์ชัน fact นี้ยังมีปัญหาอยู่ ตรงที่มันจะ terminate ไม่ได้ ถ้าใส่จำนวนเต็มลบเข้าไป

จากบรรทัดที่สอง x จะไป match กับค่าใดๆ ก็ตามที่ไม่ใช่ 0 เราอาจนึกถึงการใช้ if-else เพื่อดักตัวแปรเหมือนที่ผ่านมา อย่างไรก็ตาม Haskell มีสิ่งที่เรียกว่า guard ซึ่งเทียเท่าได้กับ switch-case ในภาษาอื่น โดยสามารถเรียกใช้งานได้เช่นนี้


นอกจากนี้ เรายังสามารถระบุ type ฟังก์ชันได้เช่นเดียวกับตัวแปร โดยเพิ่มบรรทัดนี้เข้าไปด้านบนสุดครับ




ด้านขอบเขตของตัวแปรนั้น เราเคยใช้ let เก็บค่าตัวแปรที่คำนวณเอาไว้ก่อนมาแล้ว ซึ่งนี่เป็นคำสั่งพิเศษเฉพาะบน ghci เท่านั้น เมื่อเขียนเป็นฟังก์ชันจะต้องมีส่วน in เพื่อบอกขอบเขตของตัวแปรที่โดนประกาศด้วย let เสมอ


เช่นตัวอย่างนี้จะประมาณค่า Fibonacci ในตำแหน่งที่ n โดยคำนวณค่า phi กับ psi เก็บไว้ก่อน ซึ่งมันจะถูกนำไปใช้ได้ในหลังจาก in ตรงบรรทัดที่ 3 เท่านั้นครับ

นอกจากการประกาศด้วย let-in แล้ว ยังมีอีกวิธีคือใช้ where ซึ่งคราวนี้ตัวแปรที่ถูกประกาศจะเห็นได้ทั้งฟังก์ชัน รวมถึงส่วน guard เพื่อทำ switch-case อีกด้วย


สิ่งที่ต้องระวังในการเขียนหลายบรรทัดคือการ indent (จัดย่อหน้า) สังเกตว่าประโยคหลัง where หรือ let นั้นต้อง indent ให้เท่ากัน เช่นเดียวกับส่วน let และ in ครับ

ด้านการออกแบบลำดับตัวแปรของฟังก์ชันนั้น จะให้ตัวแปรแรกๆ เป็นตัวแปรที่เปลี่ยนค่าไม่บ่อย เนื่องจากเราสามารถทำ partial application เพื่อสร้างฟังก์ชันที่มี initial value ได้เช่นนี้

No comments:

Post a Comment