Comonad คืออะไรและมีประโยชน์อย่างไร


16

เมื่อเร็ว ๆ นี้ฉันได้ปัดความรู้ของฉันเกี่ยวกับวิธีการทำงานของ Monads ฉันยังได้รับการแนะนำให้รู้จักกับแนวคิดของการเป็น'Comonad'ซึ่งจะอธิบายเป็นผกผันสองของ monad อย่างไรก็ตามฉันไม่สามารถคาดศีรษะได้

เพื่อทำความเข้าใจ Monads ฉันได้ทำการเปรียบเทียบของตัวเอง:

Monads สามารถมองเห็นเป็น 'พิมพ์เขียวเพื่อสร้างสายพานลำเลียงของการแสดงออก'

ในการกำหนด Monad ใหม่ (ระบบสายพานแบบใหม่) คุณต้องกำหนด:

  1. วิธีวางสิ่งของบนสายพานลำเลียงเช่น 'เริ่ม' สายพาน (รู้จักในชื่อunitหรือreturn)
  2. วิธีเชื่อมต่อเครื่อง (นิพจน์) ที่จะเป็นส่วนหนึ่งของสายพานลำเลียงเข้ากับสายพาน (ที่รู้จักกันjoinหรือbindหรือ>>=)

(มีการดำเนินการที่สามที่ใช้สายพานลำเลียงในปัจจุบันโยนเนื้อหาออกไปและเริ่มสายพานลำเลียงใหม่ที่รู้จักกันในนาม>>แต่ใช้งานบ่อยครั้งมาก)

เพื่อให้เครื่องจักรและสายพานทำงานร่วมกันอย่างเหมาะสมคุณจะต้องตรวจสอบให้แน่ใจว่า:

  1. หากคุณใส่อะไรลงบนสายพานลำเลียงและส่งผ่านเครื่องผลลัพธ์ที่ได้ควรจะเหมือนกับเมื่อคุณส่งผ่านเครื่องด้วยตนเอง (ข้อมูลประจำตัวด้านซ้าย)
  2. หากคุณต้องการใส่สายพานลำเลียงระหว่างสายพานที่มีอยู่แล้วคุณไม่ควรท้ายด้วยสายพานลำเลียงที่มีสายพานลำเลียงอยู่ด้านบน แต่ควรเป็นสายพานที่ยาวกว่า (เอกลักษณ์ที่ถูกต้อง)
  3. มันไม่สำคัญสำหรับผลลัพธ์ถ้าคุณใช้เครื่อง A ด้วยตนเองแล้วส่งผลลัพธ์ผ่าน BC ที่เชื่อมต่อกับเครื่องลำเลียงหรือถ้าคุณใช้ AB ที่เชื่อมต่อกับเครื่องลำเลียงแล้วจากนั้นส่งผลลัพธ์ด้วยตนเองผ่าน C ในคำอื่น ๆ : (( >> = b) >> = c) ควรเหมือนกับ (a >> = (b >> = c)) (Associativity)

สายพานลำเลียงที่ง่ายที่สุดจะเป็นสายพานที่รับเข้ามาและจะดำเนินต่อไปยังนิพจน์ถัดไป นี่คือสิ่งที่ 'ท่อ' คือ

ความเป็นไปได้อีกอย่างหนึ่งคือการปล่อยให้มันผ่านเครื่องถัดไปหากเงื่อนไขบางอย่างตรงกับค่า ซึ่งหมายความว่าหากบางนิพจน์อยู่ระหว่างค่าจะเปลี่ยนเป็นบางสิ่งที่ไม่ได้รับอนุญาตอีกต่อไปส่วนที่เหลือของนิพจน์จะถูกข้ามไป นี่คือสิ่งที่ 'อาจจะ' monad ทำใน Haskell

นอกจากนี้คุณยังสามารถทำตามกฎการคัดลอก / เปลี่ยนแปลงเงื่อนไขแฟนซีอื่น ๆ เกี่ยวกับค่าก่อนหรือหลังจากที่คุณส่งไปยังเครื่อง ตัวอย่าง: ตัวแยกวิเคราะห์ (ที่นี่หากนิพจน์ส่งคืนผลลัพธ์ 'ความล้มเหลว' ค่าจาก ก่อนที่นิพจน์จะใช้เป็นเอาต์พุต)

แน่นอนว่าการเปรียบเทียบนั้นไม่สมบูรณ์แบบ แต่ฉันหวังว่ามันจะให้การเป็นตัวแทนที่ดีของวิธีการทำงานของ monads

อย่างไรก็ตามฉันมีปัญหามากมายที่จะเปิดการเปรียบเทียบนี้บนหัวของมันเพื่อทำความเข้าใจ Comonads ฉันรู้จากข้อมูลจำนวนเล็กน้อยที่ฉันพบบนอินเทอร์เน็ตที่ Comonad กำหนด:

  • extractซึ่งเป็นการเรียงลำดับย้อนกลับของreturnนั่นคือมันใช้ค่าออกจาก Comonad
  • duplicateซึ่งเป็นสิ่งที่ตรงกันข้ามกับjoinกล่าวคือมันสร้าง Comonads สองอันจากอันเดียว

แต่ Comonad สามารถสร้างอินสแตนซ์ได้อย่างไรถ้าเราสามารถดึงออกมาจากพวกมันหรือทำซ้ำพวกมันได้? และพวกเขาสามารถนำไปใช้จริงได้อย่างไร? ฉันได้เห็นโครงการที่น่าอัศจรรย์นี้มากและการพูดคุยเกี่ยวกับมัน (ซึ่งฉันโชคไม่ดีที่เข้าใจน้อยมาก) แต่ฉันไม่แน่ใจว่า Comonad เป็นส่วนหนึ่งของฟังก์ชั่นใดบ้าง

Comonad คืออะไร มีประโยชน์อะไรบ้าง? พวกเขาจะถูกนำไปใช้อย่างไร? พวกมันกินได้หรือไม่?


2
"Comonad สามารถสร้างอินสแตนซ์ได้อย่างไรถ้าเราสามารถดึงออกมาจากพวกมันหรือทำซ้ำพวกมันได้?" - ฉันจะตอบคำถามของคุณด้วยคำถาม: Monad จะถูกใช้ไปได้อย่างไรถ้าคุณสามารถเพิ่มคุณค่าให้กับพวกเขาและการคำนวณตามลำดับเท่านั้น
Benjamin Hodgson

1
"เครื่องในตอนท้ายของสายพานลำเลียง" (นอกเหนือ: ฉันไม่พบอุปมาทุกสิ่งที่เป็นประโยชน์เมื่อพูดคุยเกี่ยวกับ monads) ของIOmonad เป็นระบบรันไทม์ Haskell mainซึ่งจะเรียก นอกจากนี้ยังมีunsafePerformIOแน่นอน หากคุณต้องการที่จะคิดของMaybemonad ว่าเป็น "เครื่องในตอนท้ายของสายพานลำเลียงที่" maybeคุณสามารถใช้
Benjamin Hodgson

1
แต่การหันคำอธิบายของคุณไปรอบ ๆ เมื่อคุณต้องการสร้างมูลค่า comonadic ที่จุดเริ่มต้นของห่วงโซ่ของcobindแอปพลิเคชันจะต้องมีฟังก์ชั่นบางอย่างที่ทำสิ่งที่มีประโยชน์กับการเป็นตัวแทนภายในของ comonad ของคุณ
Benjamin Hodgson

2
อินสแตนซ์ที่เฉพาะเจาะจงของ comonad หรือ monad สามารถมีฟังก์ชันการทำงานได้อย่างชัดเจนมากกว่าที่ต้องการเพียงแค่ใช้ typeclasses
jk

2
ไม่ใช่ว่ามันจะมีประโยชน์ถ้าคุณไม่เข้าใกล้คำถามนี้จากด้านหมวดหมู่ทฤษฎี / คณิตศาสตร์ แต่ฉันอยากจะชี้ให้เห็นว่า comonad ไม่ใช่สิ่งตรงกันข้าม แต่เป็นคู่ของ monad
Jörg W Mittag

คำตอบ:


11

comonad คือเช่นเดียวกับ monad โครงสร้างทางคณิตศาสตร์ในทฤษฎีหมวดหมู่ Co-prefix นั้นเป็นเรื่องธรรมดามากที่จะแสดง "inverses" ตามที่คุณใส่ไว้ (แม้ว่าฉันจะไม่คิดว่านักคณิตศาสตร์ล้วนเห็นด้วยกับการเลือกคำ)

ในหมวดหมู่ทฤษฎีมีcategoriesซึ่งวางชุดของobjects(ประเภทหรือธรรมชาติใด ๆ โครงสร้างภายในไม่เกี่ยวข้อง) และarrowsระหว่างวัตถุเหล่านี้ สำหรับสิ่งที่จะเป็นหมวดหมู่ลูกศรจะต้องปฏิบัติตามกฎหมายบางอย่าง (ซ้าย / ขวา - ตัวตนและการเชื่อมโยง) แต่นั่นไม่สำคัญจริงๆที่นี่

ทีนี้ทฤษฎีหมวดหมู่ทั้งนามธรรม / ยากที่จะห้อมล้อมและกว้างใหญ่ มันต้องใช้เวลามากของเวลาที่จะผ่านมันไปทั้งหมด (และฉันยังไม่ได้ศึกษามันอย่างเป็นทางการฉันเพียงรู้พื้นฐานบางอย่าง) dualแต่มีความคิดที่ใช้ที่เรียกว่า โดยทั่วไปสำหรับทุกหมวดหมู่คุณสามารถสร้างopposite categoryโดยเพียงแค่ทำสิ่งเดียวกัน แต่ "ย้อนกลับลูกศรทั้งหมด" นี่เป็นคำจำกัดความที่ไร้เดียงสามาก แต่ก็ยากที่จะสรุป คู่ของบางอย่างในหมวดหมู่ C นั้นเป็นสิ่งเดียวกันในหมวดหมู่ที่ตรงกันข้าม C_op (ปวดหัวหรือยัง)

อย่างไรก็ตามหากคุณมี monad ในบางหมวดหมู่ (และประเภทหนึ่งสามารถเป็นประเภทที่วัตถุเป็นชนิดในภาษาการเขียนโปรแกรมบางส่วนและลูกศรเป็นฟังก์ชั่นระหว่างประเภท) จากนั้น comonad ก็เป็นสิ่งเดียวกันเท่านั้น มีการย้อนกลับลูกศรทั้งหมด (เช่นกลับรายการลายเซ็นฟังก์ชันในกรณีนี้)

มากกว่า "มือบน" คำอธิบาย (แม้ว่าบนมือไม่ SUPER) สามารถพบได้ในนี้การอภิปรายระหว่างเอริคเมย์เยอร์และไบรอันเบคค์ที่พวกเขากำลังคุยกันเรื่องความคิดของคู่และวิธีการที่เอริคไปเกี่ยวกับ "การย้อนกลับของลูกศร" สำหรับIEnumerable<T>ใน C # เมื่อ สร้างกรอบปฏิกิริยาและIObservable<T>(ซึ่งเท่าที่ฉันสามารถบอกได้และฉันยินดีที่จะได้รับการแก้ไขโดยทั่วไปเป็นอินสแตนซ์ของรายการ comonad)

อีกตัวอย่างการปฏิบัติของ comonads ที่กล่าวถึงในวิดีโอคือTask<T>ประเภทใน. NET ซึ่งTask<U> ContinueWith<U>(Func<Task<T>, U>)จะเป็นสองของbind(หรือSelectManyที่เรียกว่าใน C #)


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.