:t
ตรวจชนิดของฟังก์ชันดูบ้าง จะเห็นแบบนี้ส่วนที่บอก type จะอยู่หลังเครื่องหมาย
=>
เช่นเคย โดยฝั่งซ้ายของ ->
จะเป็นตัวแปรที่รับเข้ามาในฟังก์ชัน ส่วนฝั่งขวาคือผลลัพท์จากฟังก์ชัน นั่นหมายความว่าฟังก์ชัน fromIntegral
รับตัวแปรใน type class Integral
แล้วได้ผลลัพท์เป็น type class Num
การเขียนฟังก์ชันนั้น เช่นเดียวกับการประกาศค่าคงที่ คือใช้
let
พร้อมชื่อฟังก์ชันและตัวแปร เช่นทีนี้ลองดูฟังก์ชันของ 2 ตัวแปรกันบ้าง
สิ่งที่แตกต่างไปจากภาษา imperative และถือได้ว่าเป็นจุดเด่นของภาษาแบบ functional เลยคือ แทนที่ type ของฟังก์ชัน 2 ตัวแปรจะใช้ช่องว่างคั่นตัวแปร (type น่าจะอยู่ในรูป
a a -> a
) แต่ระหว่างตัวแปรกลับใช้สัญลักษณ์ ->
เช่นเดียวกับการบอกผลลัพท์ที่ได้จากฟังก์ชันเราอาจลองแบ่งกลุ่มเพื่อความกระจ่างใน type ว่ามันคือ
a -> (a -> a)
ซึ่งหมายความว่า ฟังก์ชันนี้เป็นฟังก์ชันที่รับตัวแปร 1 ตัว แล้วให้ผลลัพท์เป็นฟังก์ชันที่รับตัวแปร 1 ตัวแล้วคืนค่าออกมาก็ย่อมได้นั่นหมายความว่า ฟังก์ชัน 2 ตัวแปร แท้จริงแล้วคือฟังก์ชัน 1 ตัวแปร 2 ชั้น เราจึงสามารถเรียกฟังก์ชันแบบนี้
ได้เช่นกัน นี่เป็นเหตุผลว่าทำไม Haskell ถึงไม่ใช้วงเล็บล้อมรอบตัวแปร เราเรียกเทคนิคการทำให้ฟังก์ชันหลายตัวแปรกลายร่างเป็นฟังก์ชันตัวแปรเดียวซ้อนๆ กันเช่นนี้ว่า currying และเรียกฟังก์ชันที่รับตัวแปรเข้าไปแล้วบ้างแต่ยังไม่ครบว่า partial application ครับ
อนึ่ง เราสามารถเขียนการหารเก็บเศษข้างบนเป็นแบบนี้
123456789 `mod` 1009
และถ้าเราต้องการเอาวงเล็บล้อมรอบ `mod` 1009
ด้านหลัง มันจะกลายเป็นฟังก์ชันที่รับตัวแปรไปแล้ว 1 ตัว และต้องการอีก 1 ที่ต้องทำต่อคือย้ายมันไปไว้ข้างหน้าเท่านั้นเองซึ่งสามารถจับมาประกาศเป็นฟังก์ชันได้ว่า
หรือยิ่งไปกว่านั้น
กลับไปดูฟังก์ชัน
half
ที่เขียนไว้ตอนต้นอีกที เราลองเขียนมันใหม่เป็นจะเห็นว่าไม่เพียงแต่ฟังก์ชันเท่านั้น ที่เราสามารถนำวงเล็บไปล้อมรอบได้ แต่นี่ยังรวมไปถึง operator ด้วย นอกจากนี้
นั่นหมายความว่า operator เหล่านั้นก็ถือเป็นฟังก์ชันเช่นเดียวกันนั่นเอง
No comments:
Post a Comment