Io

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

    ghci> let c = 'a'
    ghci> let s = "abc"

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

    ghci> :t "this is a string"
    "this is a string" :: [Char]

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

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

    ghci> "Hello " ++ "Nick" ++ "."
    "Hello Nick."

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

    ghci> "Grade: " ++ ['A']
    "Grade: A"

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

    ghci> "Point: " ++ show 87.5
    "Point: 87.5"

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

    ghci> read "23" + 19
    42

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

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

    ghci> read "23" :: Float
    23.0

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

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

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

    ghci> input <- getLine

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

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

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

    main = do
        putStrLn "what is x?"
        x <- getLine
        putStrLn "what is y?"
        y <- getLine
        putStrLn "then z is:"
        print (sqrt ((read x)**2 + (read y)**2))
        main

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

Nattawut Phetmak

Jack of all Trades

blog comments powered by Disqus