December 11, 2012

Haskell: ข้อความและ IO เบื้องต้น

ใน Haskell จะแบ่งข้อมูลตัวอักษรเป็น 2 แบบ ได้แก่ Char (อักษร 1 ตัว) ที่ประกาศโดยใช้ single quote ส่วน String (อักษรหลายตัว) ประกาศโดยใช้ double quote


อย่างไรก็ตาม ถ้าลองตรวจสอบ type ของ String จะเห็นแบบนี้


วงเล็บปีกแข็งที่ครอบ Char นั้นบอกว่า String เป็นข้อมูลแบบ List ของ Char (คือการเอา Char หลายๆ ตัวมาต่อกัน)

การเชื่อม String เข้าด้วยกัน ทำได้โดยวางเครื่องหมาย ++ ไว้ระหว่างข้อความ 2 ข้อความ


อย่างไรก็ตาม การเชื่อม String กับ Char ต้องแปลง type ของ Char ให้เป็น String เสียก่อน


ถ้าต้องการแสดงตัวเลข (และข้อมูลชนิดอื่นๆ) ให้ใช้ฟังก์ชัน show แทน


ส่วนการแปลง type จากข้อความไปเป็น type อื่นเพื่อนำไปคำนวณต่อ สามารถทำได้ผ่านฟังก์ชัน read เช่นนี้


แต่การสั่ง read "23" เพียงอย่างเดียวจะเกิด error เพราะตัวแปรนั้นจะหา type ไม่ได้ (เนื่องจากไม่รู้ว่าจะถูกเอาไปใช้ทำอะไรต่อ)

ทางออกคือถ้ารู้ type ที่จะเอาไปใช้ต่อแน่นอน ก็กำหนดลงไปได้เลย




เนื่องจากหลักการของภาษาเชิง functional นั้นบอกว่า ฟังก์ชันใดๆ ที่เรียกขึ้นมาโดยส่งผ่านตัวแปรเดิมเข้าไป ผลลัพท์ก็ต้องออกมาเหมือนเดิมเสมอ

ตัวแปรของฟังก์ชันในที่นี้ คือตัวแปรที่กำหนดโดยโปรแกรมเมอร์ ไม่ใช่ IO จากฝั่งผู้ใช้ ดังนั้นถ้ายึดตามหลักนี้ โปรแกรมเดียวกันจะให้ผลลัพท์เดิมทุกครั้ง (เพราะ IO ที่รับมาจากผู้ใช้ไม่มีความหมาย) Haskell แก้ปัญหานี้โดยการนิยามฟังก์ชันสำหรับจัดการ IO แยกออกมาโดยเฉพาะ

เมื่อต้องการรับข้อความเป็นบรรทัดจากผู้ใช้ ทำได้โดยฟังก์ชัน getLine ดังนี้


ฟังก์ชันนี้จะรอเราพิมพ์ข้อความไปเรื่อยๆ จนกว่าจะป้อน EOL ให้ สังเกตว่าการเก็บผลลัพท์นั้นไม่ได้ใช้ let แล้วตามด้วย = แล้ว แต่เปลี่ยนมาใช้ <- แทน ซึ่งเป็นสัญลักษณ์พิเศษสำหรับเก็บค่า String ที่รับมาจาก IO ครับ

อนึ่ง การพิมพ์ค่าโดยฟังก์ชัน putStrLn นั้น ตัวแปรแบบต้องเป็นข้อความเท่านั้น ถ้าต้องการพิมพ์ค่าตัวแปรที่ไม่ใช่ข้อความ สามารถใช้ฟังก์ชัน print แทนได้

ตัวอย่างต่อไปนี้เป็นโปรแกรมแบบ IO คอยรับข้อมูลจากผู้ใช้ แล้วคำนวณด้านที่ยาวที่สุดของสามเหลี่ยมมุมฉากครับ

หมายเหตุว่าการ recursive main นั้นเป็นเรื่องปรกติใน Haskell ครับ

No comments:

Post a Comment