ghci
ถ้าเราลองทำอย่างนี้let x = 10 let x = x + 1กด Enter แล้วจะพบ prompt รอทำงานต่อ ถึงตอนนี้อาจคิดว่าไม่มีปัญหาหนิ แต่อย่าลืมว่า Haskell เป็น lazy language ดังนั้นต้องเรียก
x
ออกมาดูค่าด้วย... แล้วเราก็จะพบกับความว่างเปล่า เฮ้ยทำไมแค่บวกเลขง่ายๆ มันถึงคิดช้าจังฟระ
นั่นเป็นเพราะว่ารูปด้านบนนี้เป็น recursive ตอนที่จะ eval ค่า
x + 1
ด้านขวามือออกมา มันจะไปเรียกดู definition ของ x
ซึ่งก็คือ x + 1
นั่นเอง (ลืมไปได้เลยว่าเราเคยบอกให้ x = 10
)อย่างไรก็ตาม ถ้าเราเปลี่ยนไปเขียนแบบนี้
let x = 10 let y = x + 1 let x = yเวลาเรียก
x
เราจะได้คำตอบที่ถูกต้องคือ 11
แล้วครับแต่ถ้าทำท่าข้างบนนี้ มันก็คงบาปพอๆ กับ
word = "abracadabra" for i in range(len(word)): print(word[i])ใน Python นั่นแหละ :P
ดังนั้น Haskell จะเลี่ยงไปใช้ Monad แทน
x <- return 10 x <- return (x + 1)ดูเผินๆ เหมือนว่าเราจะเปลี่ยนค่าตัวแปร
x
ได้ แต่ที่จริงแล้วสองบรรทัดข้างบนนี้จะเทียบเท่ากับreturn 10 >>= \x -> return (x + 1) >>= \x -> return xนั่นหมายความว่า แรกสุดเราเอาค่า
10
ส่งให้ฟังก์ชั่นที่รับตัวแปร 1 ตัว โดยฟังก์ชั่นนี้อ่านชื่อตัวแปรที่รับมาว่า x
แล้วจึงคำนวณ x + 1
เรียบร้อยแล้วก็ส่งต่อค่าที่คำนวณได้ไปให้ฟังก์ชั่นอีกตัว ที่รับตัวแปร 1 ตัวและอ่านชื่อตัวแปรนั้นว่า x
เช่นกันจะเห็นว่าแท้จริงแล้วเราไม่ได้เปลี่ยนค่าของตัวแปรเลย มันเป็นเพียงการส่งต่อค่าที่คำนวณแล้วให้ฟังก์ชันอื่นไปเรื่อยๆ โดยที่ฟังก์ชั่นเหล่านั้นบังเอิญเรียกชื่อตัวแปรเหมือนกันเท่านั้นเอง
No comments:
Post a Comment