Numbers

ระบบชนิดตัวแปรของ Haskell จะแตกต่างจากภาษาอื่นๆ ตรงที่แบ่งออกได้เป็น 2 ส่วน คือ

  1. type class ลำดับชั้นของตัวแปรที่บ่งบอกความสัมพันธ์กับฟังก์ชันต่างๆ
  2. type ชนิดของตัวแปร โดยตัวแปรชนิดนึงสามารถมีได้หลาย class

อาจมองได้ง่ายๆ อีกอย่างว่า type คือวิธี implement ข้อมูล ส่วน type class จะเป็นตัวกำหนดความสามารถของ type นั้นๆ ครับ

ซึ่งตัวเลขใน Haskell สามารถจัดแบ่งคร่าวๆ ได้ดังนี้

  • ตัวเลข class: Num
    • จำนวนเต็ม class: Integral
    • ทศนิยม class: Floating, Fractional
      • type: Float ทศนิยมแบบ single ความละเอียด 9 หลัก
      • type: Double ทศนิยมแบบ double ความละเอียด 18 หลัก

และเราสามารถตรวจสอบ type ได้โดยใช้ command :t (หรือเต็มๆ คือ :type) แล้วตามด้วยตัวแปร เช่น

    ghci> :t 42
    42 :: Num a => a
    ghci> :t 1.0
    1.0 :: Fractional a => a
    ghci> :t 42 + 1.0
    42 + 1.0 :: Fractional a => a

type class พร้อมตัวแปรที่ใช้แสดงแทนนั้น จะถูกบอกไว้ก่อนเครื่องหมาย => ส่วนอีกด้านจะบอก type ของตัวแปร ซึ่งในกรณีที่เราไม่ได้เจาะจง type ลงไปเช่นนี้ Haskell จะจัดมันไว้ใน type class ที่ใหญ่ที่สุดไว้ก่อน เพื่อที่ว่าถ้าดำเนินการกับ type class ที่เป็นลูกหลานของมันจะยังให้ผลลัพท์ที่ถูกต้อง

ส่วนการประกาศ type แบบเจาะจงก็ทำได้โดยใส่ 2 colon แล้วตามด้วย type ไว้ข้างหลังตัวแปรนั้น

    ghci> let answer = 42 :: Float
    ghci> :t answer
    answer :: Float

จะเห็นว่าคราวนี้ไม่มีการบอก type class กับ => แล้ว เพราะเรารู้ type ที่แน่นอนของมันนั่นเอง

อย่างที่บอกไว้แต่ต้น การดำเนินการข้าม type หรือ type class ที่ไม่เกี่ยวข้องกันนั้น ไม่สามารถทำได้ใน Haskell เช่น error ในตัวอย่างนี้

    ghci> (1 :: Int) + (1 :: Integer)

    <interactive>:2:15:
        Couldn't match expected type `Int' with actual type `Integer'
        In the second argument of `(+)', namely `(1 :: Integer)'
        In the expression: (1 :: Int) + (1 :: Integer)
        In an equation for `it': it = (1 :: Int) + (1 :: Integer)

เลขทั้งสองตัวนั้นก็ต่างอยู่ใน type class Integral เหมือนกัน แต่เมื่อถูกกำหนดโดย type ต่างกัน จะทำให้ไม่สามารถนำมาบวกกันได้

ทางออกคือ

  • จำนวนเต็มสามารถใช้ฟังก์ชัน fromIntegral เพื่อเปลี่ยน type class กลับไปเป็น Num ก่อนเอาไปคำนวณต่อ
  • ทศนิยมใช้ฟังก์ชัน truncate (ปัดทิ้ง), floor (ปัดลง), ceiling (ปัดขึ้น), round (ปัดครึ่ง) เพื่อเปลี่ยน type class เป็น Integral ได้

Nattawut Phetmak

Jack of all Trades

blog comments powered by Disqus