ทำความเข้าใจกับฟังก์ชั่นการพลิก

ฉันกำลังเรียนรู้ฟังก์ชันระดับสูงจาก 'Learn You a Haskell for Great Good!' โดย มิรัน ลิโปวากา.

สำหรับการพลิกฟังก์ชันต่อไปนี้ซึ่งรับฟังก์ชันและส่งกลับฟังก์ชันโดยพลิกอาร์กิวเมนต์สองข้อแรก:

flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = g
   where g x y = f y x

ฉันไม่เข้าใจว่า f และ g คืออะไร พวกเขาทั้งสองมีหน้าที่แตกต่างกันหรือไม่? ในทำนองเดียวกัน ในการผูกตรงไหน g x y = f y x หมายถึงอะไรกันแน่?


person ceno980    schedule 04.06.2019    source แหล่งที่มา


คำตอบ (2)


ในไวยากรณ์:

myFunction x = x + 2

สิ่งที่อยู่ทางด้านซ้ายของเครื่องหมายเท่ากับ x จะถือเป็น "พารามิเตอร์" คุณสามารถใช้มันบนเครื่องหมายทางขวามือของเครื่องหมายเท่ากับเพื่อระบุว่าคุณต้องการให้ผลลัพธ์เป็นอย่างไร

ไวยากรณ์นี้กำหนดฟังก์ชัน myFunction โดยมีพารามิเตอร์เดียว x

ดังนั้นเราจึงมี:

flip' f = g

สิ่งนี้จะกำหนดฟังก์ชัน flip' โดยมีพารามิเตอร์เดียว f

เรามีคำจำกัดความอื่นเช่นกัน:

g x y = f y x

ซึ่งจะกำหนดฟังก์ชัน g โดยมีพารามิเตอร์สองตัว คือ x และ y

ดังนั้นเมื่อเราพูดว่า:

flip' f = g
  where
    g x y = f y x

เรากำลังบอกว่าผลลัพธ์ของ flip f คือฟังก์ชัน g โดยที่ g ถูกกำหนดเป็น g x y = f y x

ในกรณีที่ชื่อตัวแปรแบบสั้นทำให้คุณสับสน นี่คือฟังก์ชันเดียวกันกับชื่อบางส่วนที่ถูกสลับเพื่อความชัดเจน:

flippity flop = glop
  where
    glop x y = flop y x

ดูว่าคุณสามารถเข้าใจสิ่งที่ flippity ทำได้หรือไม่ และดูว่าคุณสามารถดูว่ามันเหมือนกับ flip' อย่างไร เพียงแต่มีพารามิเตอร์ภายในและชื่อฟังก์ชันตัวช่วยที่แตกต่างกัน

โปรดจำไว้ว่าใน Haskell ว่าเราสามารถเปลี่ยนการเรียกใช้ฟังก์ชันตามร่างกายได้ตลอดเวลาเป็นส่วนใหญ่ ดังนั้นเราจึงเขียนมันใหม่ได้เป็น:

flippity flop = glop
  where
    glop = \x y -> flop y x

-- replace glop with its definition

flippity flop = \x y -> flop y x

เราจะเห็นว่า flippity เป็นฟังก์ชันที่รับฟังก์ชัน flop และส่งกลับฟังก์ชันใหม่ \x y -> flop y x

person Justin L.    schedule 04.06.2019
comment
คุณสามารถก้าวไปอีกขั้นหนึ่งแล้วพูดว่า flippity flop x y = flop y x แต่มันทำให้เรื่องสับสนมากขึ้น - person talex; 04.06.2019
comment
@talex จะไม่ หนึ่ง ก้าวต่อไปเป็น flippity flop x = \y -> flop y x :P - person moonGoose; 04.06.2019
comment
นั่นคือขั้นตอนของทารกที่แท้จริง :) - person talex; 04.06.2019

f คืออินพุตของ flip' (ฟังก์ชันที่คุณต้องการพลิก), g คือเอาต์พุต flip's (ฟังก์ชันที่พลิกแล้วจะกลับมา)

ส่วนคำสั่ง where เป็นเพียงการกำหนดว่า g คืออะไร; นั่นคือการกำหนดฟังก์ชันที่เรียก f โดยที่อาร์กิวเมนต์กลับด้าน

คุณสามารถหลีกเลี่ยงการตั้งชื่อ g ได้เลยโดยเพียงแค่ให้ flip' ส่งกลับแลมบ์ดา:

flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = \x y -> f y x
person typedfern    schedule 04.06.2019