พวกเขามีลักษณะเหมือนกันบนไซต์แอปพลิเคชัน แต่แน่นอนว่าแตกต่างกัน เมื่อคุณใช้ฟังก์ชันทั้งสองนี้map
หรือfmap
กับรายการของค่าฟังก์ชันเหล่านี้จะให้ผลลัพธ์เดียวกัน แต่ไม่ได้หมายความว่ามีจุดประสงค์เดียวกัน
เรียกใช้เซสชัน GHCI (Glasgow Haskell Compiler Interactive) เพื่อสอบถามข้อมูลเกี่ยวกับฟังก์ชันทั้งสองนี้จากนั้นดูการนำไปใช้งานและคุณจะพบความแตกต่างมากมาย
แผนที่
สอบถาม GHCI สำหรับข้อมูลเกี่ยวกับ map
Prelude> :info map
map :: (a -> b) -> [a] -> [b]
และคุณจะเห็นมันกำหนดเป็นฟังก์ชั่นสูงเพื่อใช้บังคับกับรายการของค่าประเภทใดให้ผลผลิตรายการของค่าประเภทใดa
ๆ b
แม้ว่า polymorphic ( a
และb
ในนิยามข้างต้นหมายถึงประเภทใด ๆ ) map
ฟังก์ชันนี้มีจุดมุ่งหมายเพื่อนำไปใช้กับรายการค่าซึ่งเป็นประเภทข้อมูลที่เป็นไปได้เพียงประเภทเดียวในหมู่อื่น ๆ ใน Haskell map
ฟังก์ชั่นไม่สามารถนำไปใช้กับบางสิ่งบางอย่างซึ่งไม่ได้เป็นรายการค่า
ดังที่คุณสามารถอ่านได้จากซอร์สโค้ดGHC.Basemap
ฟังก์ชันจะมีการใช้งานดังนี้
map _ [] = []
map f (x:xs) = f x : map f xs
ซึ่งใช้การจับคู่รูปแบบเพื่อดึงส่วนหัว (the x
) ออกจากส่วนท้าย (the xs
) ของรายการจากนั้นสร้างรายการใหม่โดยใช้ตัว:
สร้างค่า (ข้อเสีย) เพื่อนำหน้าf x
(อ่านว่า"f ใช้กับ x" ) ไปที่การเรียกซ้ำของmap
ส่วนหางจนกว่ารายการจะว่างเปล่า เป็นที่น่าสังเกตว่าการใช้งานmap
ฟังก์ชั่นไม่ได้ขึ้นอยู่กับฟังก์ชั่นอื่นใด แต่เพียงแค่ตัวมันเอง
fmap
ตอนนี้ลองค้นหาข้อมูลเกี่ยวกับfmap
และคุณจะเห็นสิ่งที่แตกต่างออกไป
Prelude> :info fmap
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
...
เวลานี้fmap
ถูกกำหนดให้เป็นหนึ่งในฟังก์ชันที่ต้องมีการใช้งานโดยประเภทข้อมูลเหล่านั้นซึ่งต้องการให้เป็นของFunctor
คลาสชนิด นั่นหมายความว่าอาจมีประเภทข้อมูลมากกว่าหนึ่งชนิดไม่เพียง แต่ประเภทข้อมูล"รายการค่า"เท่านั้นที่สามารถจัดเตรียมการใช้งานสำหรับfmap
ฟังก์ชัน นั่นทำให้fmap
สามารถใช้ได้กับชุดข้อมูลที่ใหญ่กว่ามาก: functors แน่นอน!
ดังที่คุณสามารถอ่านได้จากซอร์สโค้ดGHC.Baseการใช้งานfmap
ฟังก์ชันที่เป็นไปได้คือสิ่งที่จัดเตรียมโดยMaybe
ประเภทข้อมูล:
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
และการใช้งานอื่นที่เป็นไปได้คือสิ่งที่จัดทำโดยประเภทข้อมูล 2 ทูเพิล
instance Functor ((,) a) where
fmap f (x,y) = (x, f y)
และการนำไปใช้งานอื่นที่เป็นไปได้คือสิ่งที่จัดทำโดยประเภทข้อมูลรายการ (แน่นอน!):
instance Functor [] where
fmap f xs = map f xs
ซึ่งขึ้นอยู่กับmap
ฟังก์ชัน
สรุป
map
ฟังก์ชั่นสามารถนำไปใช้อะไรมากไปกว่ารายการค่า (ที่มีค่าของชนิดใด ๆ ) ในขณะที่fmap
ฟังก์ชั่นสามารถนำมาใช้ชนิดข้อมูลที่มากขึ้น: ทั้งหมดของผู้ที่อยู่ในชั้นเรียน functor (เช่น maybes, tuples, รายการ, ฯลฯ ). ตั้งแต่"รายการของค่า"ชนิดข้อมูลยังเป็น functor (เพราะมีการดำเนินการมัน) แล้วสามารถนำไปใช้เป็นเช่นเดียวกับการผลิตเดียวกันผลเป็นอย่างมากfmap
map
map (+3) [1..5]
fmap (+3) (Just 15)
fmap (+3) (5, 7)