หน้านี้เป็นการบ้านโปรแกรมที่หนึ่งของวิชา 204435
Main> mylast [1,2,3,4] 4 Main> mylast [1,2,3,4,5] 5
เราสามารถเขียนระบุ “ฟังก์ชัน” ใน Haskell ได้ในลักษณะเดียวกับการเขียนค่าทั่วไป (นั่นคือไม่ต้องระบุ “ชื่อ” ของฟังก์ชันนั้น) โดยใช้ lambda ยกตัวอย่างเช่น ฟังก์ชันที่รับค่า x
แล้วคืนค่า x+1
สามารถเขียนได้ดังนี้
\x -> x+1
ดังนั้นเราสามารถเรียกฟังก์ชันดังกล่าวได้ เช่น
Main> (\x -> x+1) 5 6
รูปแบบการเขียนดังกล่าวคือ
\ชี่อตัวแปร -> ค่าของฟังก์ชัน
ถ้าต้องการฟังก์ชันที่รับหลายตัวแปร เราสามารถเขียนเช่น
\x -> \y -> x + y
ซึ่งเป็นการนิยามฟังก์ชันบวกจำนวนสองจำนวน
การเขียนดังกล่าว เป็นการระบุฟังก์ชันโดยไม่ระบุชื่อ ด้วยวิธีการเขียนดังกล่าว เราสามารถนิยามฟังก์ชัน compose
ที่รับฟังก์ชัน f
และ g
แล้วคือฟังก์ชัน f o g
ได้ดังนี้
compose f g = \x -> (f (g x))
a. จงหาผลลัพธ์ของนิพจน์ต่อไปนี้ compose (\x → x+1) (\x → x*2) 10
b. (สำหรับข้อนี้สามารถดูแบบฝึกหัดท้ายบท 3.4 ประกอบ) เขียนฟังก์ชัน mapcar
ที่รับฟังก์ชัน f
และลิสต์ จากนั้นคืนค่าลิสต์ที่มีสมาชิกเป็นผลลัพธ์จากการ apply f
เข้ากับสมาชิกทุกตัวของลิสต์ที่รับมา เช่น
Main> mapcar (\x -> x+1) [1,2,3,4] [2,3,4,5]
c. เขียนฟังก์ชัน myfilter
ที่รับฟังก์ชัน f
สำหรับเลือกสมาชิก และลิสต์ L
จากนั้น คือลิสต์ที่ประกอบไปด้วยสมาชิกที่ฟังก์ชัน f
คืนค่าจริง (ผ่านการทดสอบจาก f
)
Main> myfilter (\x -> (x > 10)) [1,3,5,11,14,9,12] [11,14,12]
ฟังก์ชัน foldr
เป็นหนึ่งใน higher-order function ที่มีประโยชน์มาก นิยามของฟังก์ชันดังกล่าวเป็นดังนี้
foldr :: (a -> b -> b) -> b -> [a] -> b foldr f v [] = v foldr f v (x:xs) = f x (foldr v xs)
เราสามารถทำความเข้าใจกับฟังก์ชันดังกล่าวโดยพิจารณาจากตัวอย่าง ถ้าเรียก foldr f v [1,2,3]
ผลที่ได้จะเหมือนกับการสั่ง (f 1 (f 2 (f 3 v)))
เราสามารถหาผลรวมของลิสต์ได้โดยสั่ง
Main> foldr (+) 0 [1,2,3,4,5] 15
นั่นคือจะมีผลเหมือนกับสั่ง (+ 1 (+ 2 (+ 3 (+ 4 (+ 5 0)))))
สังเกตว่าเราสามารถนิยามฟังก์ชัน newsum
ที่หาผลรวมของสมาชิกในลิสต์ได้ดังนี้
newsum :: (Num a) => [a] -> a newsum x = foldr (+) 0 x
a. นิยามฟังก์ชัน mapcar
โดยใช้ฟังก์ชัน foldr
b. นิยามฟังก์ชัน myfilter
โดยใช้ฟังก์ชัน foldr