เปลี่ยนค่าตัวแปรใน Haskell
ใน 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
เช่นกัน
จะเห็นว่าแท้จริงแล้วเราไม่ได้เปลี่ยนค่าของตัวแปรเลย มันเป็นเพียงการส่งต่อค่าที่คำนวณแล้วให้ฟังก์ชันอื่นไปเรื่อยๆ โดยที่ฟังก์ชั่นเหล่านั้นบังเอิญเรียกชื่อตัวแปรเหมือนกันเท่านั้นเอง
author