ตอนม.ปลาย คงเคยเห็นฟังก์ชั่นที่เขียนแทนด้วยสัญลักษณ์ g o f กันมาแล้ว ซึ่งมันหมายความง่ายๆ เช่นนี้
(g o f) (x) = g(f(x))(นิยามเต็มๆ ของมันคือ ถ้า
f: X -> Y
และ g: Y -> Z
แล้ว g o f: X -> Z
---- ที่ต้องนิยามเช่นนี้เพราะเราจะสามารถละการเขียน argument x ติดไปกับนิยามได้)ในการเขียนโปรแกรม (โดยเฉพาะเชิง functional) เรามักต้องทำงานแบบฟังก์ชันต่อเนื่อง คือ output จาก function หนึ่ง จะถูกนำมาใช้เป็น input ให้ฟังก์ชันถัดไปเป็นลูกโซ่
เขียนอธิบายเป็นภาษาโปรแกรมได้คือ
first_input = x first_output = f(first_input) second_input = first_output second_output = g(second_input) y = second_outputหรือเพื่อไม่ให้เปลืองตัวแปร ทั้งหมดนี้สามารถย่อได้เหลือ
y = g(f(x))คำถามคือ ถ้าเราต้องการประกาศแค่ฟังก์ชั่นที่ทำงานต่อกันไปเรื่อยๆ เช่นนี้ โดยที่ไม่ต้องการใส่ input ให้ฟังก์ชั่นโดยทันที เราจะทำอย่างไร?
ทางออกหนึ่งคือใช้ lambda เข้าช่วย
h = lambda x: g(f(x))แล้วเวลาจะเรียกใช้ฟังก์ชั่นนี้ ก็แค่สั่ง
y = h(x)ฟังดูง่ายดี แต่นึกดูอีกที ทำไมเราถึงต้องทำอะไรให้มันยุ่งยากด้วยการเอา lambda เข้ามาเกี่ยวด้วย?
ในภาษา imperative คงไม่มีทางเลือกอื่น แต่สำหรับภาษา functional จ๋าอย่าง Haskell เราสามารถเขียนแบบนี้ได้
let h = g . fจะเห็นว่าง่ายดายเหมือนกับ g o f ตอนแรกเลย เวลาใช้ก็แค่
h xหรือถ้าจะละการประกาศฟังก์ชั่น h ทิ้งไป เพื่อหาผลลัพท์ทันทีเลย ก็ทำได้โดย
(g . f) xอ่าห์... นี่มันคณิตศาสตร์ชัดๆ!!
พอเอามาให้โปรแกรมเมอร์ non math ดู จะด่ากันกระจาย...
ReplyDeleteตรงไปตรงมาดีครับ
ReplyDelete