Monad เป็นเพียง monoid ในประเภท endofunctors ปัญหาคืออะไร


722

ใครบอกว่าต่อไปนี้ก่อน?

Monad เป็นเพียง monoid ในประเภท endofunctors ปัญหาคืออะไร

และในบันทึกย่อที่สำคัญน้อยกว่านี่คือความจริงและถ้าเป็นเช่นนั้นคุณสามารถให้คำอธิบายได้ (หวังว่าจะมีคนที่ไม่เข้าใจประสบการณ์ของ Haskell มาก)


14
ดู "หมวดหมู่สำหรับนักคณิตศาสตร์ที่ทำงาน"
Don Stewart

19
คุณไม่จำเป็นต้องเข้าใจสิ่งนี้เพื่อใช้ monads ใน Haskell จากมุมมองที่ใช้งานได้จริงพวกเขาเป็นเพียงวิธีที่ชาญฉลาดในการผ่าน "สถานะ" ผ่านการวางท่อใต้ดิน
starblue

1
ฉันต้องการเพิ่มการโพสต์บล็อกที่ยอดเยี่ยมที่นี่เช่นกัน: stephendiehl.com/posts/monads.htmlมันไม่ได้ตอบคำถามโดยตรง แต่ในความคิดของฉันสตีเฟ่นทำงานที่ยอดเยี่ยมของการผูกหมวดหมู่และพระใน Haskell ด้วยกัน หากคุณได้อ่านคำตอบข้างต้นแล้วสิ่งนี้จะช่วยให้การรวมกันของสองวิธีนี้ดูเป็นไปได้
Ben Ford

3
แม่นยำยิ่งขึ้น "สำหรับหมวดหมู่ใด ๆ หมวดหมู่ [C, C] ของ endofunctors มีโครงสร้างที่เกิดจากการประกอบ monoidal วัตถุวัตถุใน [C, C] เป็น monad c monad" - จาก en.wikipedia.org/wiki/Monoid_%28category_theory%29 ดู en.wikipedia.org/wiki/Monad_%28category_theory%29 สำหรับคำจำกัดความของ monad ในทฤษฎีหมวดหมู่

1
@Dmitry functorเป็นฟังก์ชั่นระหว่างประเภทที่มีข้อ จำกัด บางอย่างที่จะมีความประพฤติดี endofunctor ในประเภท C เป็นเพียงนักแสดงจากซีถึงตัวมันเอง Data.Functorเป็น typeclass สำหรับ endofunctors บนเป็นหมวดหมู่HAŠK เนื่องจากหมวดหมู่ประกอบด้วยวัตถุและมอร์ฟิฟิสเตอร์จึงจำเป็นต้องทำแผนที่ทั้งสองแบบ สำหรับอินสแตนซ์ f ของ Data.Functor แผนที่บนวัตถุ (ประเภท haskell) คือ f เองและแผนที่บน morphisms (ฟังก์ชัน haskell) คือ fmap
Matthijs

คำตอบ:


796

ประโยคเฉพาะนั้นคือโดย James Iry จากบทสรุปความบันเทิงที่ไม่สมบูรณ์และไม่ถูกต้องส่วนใหญ่ของประวัติศาสตร์การเขียนโปรแกรมภาษาซึ่งเขาได้กล่าวอ้างถึง Philip Wadler

ข้อความต้นฉบับมาจาก Saunders Mac Lane ในหมวดหมู่สำหรับนักคณิตศาสตร์ทำงานซึ่งเป็นหนึ่งในตำราพื้นฐานของหมวดหมู่ทฤษฎี ที่นี่มีอยู่ในบริบทซึ่งอาจเป็นสถานที่ที่ดีที่สุดในการเรียนรู้สิ่งที่มันหมายถึง

แต่ฉันจะแทง ประโยคเดิมคือ:

ทั้งหมดบอกว่า monad ใน X เป็นเพียง monoid ในหมวดหมู่ของ endofunctors ของ X ด้วยผลิตภัณฑ์×แทนที่ด้วยองค์ประกอบของ endofunctors และหน่วยที่กำหนดโดย endofunctor ตัวตน

Xนี่คือหมวดหมู่ Endofunctors มี functors จากหมวดหมู่เพื่อตัวเอง (ซึ่งมักจะทุก Functor s เท่าที่โปรแกรมเมอร์ทำงานมีความกังวลเนื่องจากพวกเขากำลังส่วนใหญ่ที่เกี่ยวข้องกับการเพียงหนึ่งหมวดหมู่; หมวดหมู่ของประเภท - แต่ฉันเชือนแช) แต่คุณสามารถจินตนาการหมวดหมู่อื่นซึ่งเป็นหมวดหมู่ของ "endofunctors on X " นี่คือหมวดหมู่ที่วัตถุคือ endofunctors และ morphisms เป็นการเปลี่ยนแปลงตามธรรมชาติ

และในบรรดา endofunctors บางคนอาจเป็นพระ อันไหนเป็นพระ อย่างแน่นอนคนที่มีmonoidalในความหมายเฉพาะ แทนที่จะสะกดการแมปที่ถูกต้องจาก monads ไปยัง monoids (เนื่องจาก Mac Lane ทำได้ดีกว่าที่ฉันคาดหวังมาก) ฉันจะใส่คำจำกัดความตามลำดับและให้คุณเปรียบเทียบ:

monoid คือ ...

  • ชุด, S
  • การดำเนินการ•: S × S → S
  • องค์ประกอบของS , e: 1 → S

... เป็นไปตามกฎหมายเหล่านี้:

  • (a • b) • c = a • (b • c)สำหรับa , bและc ทั้งหมดในS
  • e • a = a • e = a , สำหรับaทั้งหมดในS

Monad คือ ...

  • endofunctor, T: X → X (ใน Haskell ตัวสร้างชนิดที่* -> *มีFunctorอินสแตนซ์)
  • การเปลี่ยนแปลงตามธรรมชาติμ: T × T → Tโดยที่×หมายถึงองค์ประกอบของ functor ( μเป็นที่รู้จักjoinใน Haskell)
  • การเปลี่ยนแปลงตามธรรมชาติη: I → Tที่ซึ่งฉันเป็นตัวตนของ endofunctor ในX ( ηเป็นที่รู้จักreturnใน Haskell)

... เป็นไปตามกฎหมายเหล่านี้:

  • μ∘Tμ = μ∘μT
  • μ∘Tη = μ∘ηT = 1 (การเปลี่ยนแปลงทางธรรมชาติของตัวตน)

กับบิตของ squinting คุณอาจจะสามารถที่จะเห็นว่าทั้งสองของคำนิยามเหล่านี้เป็นกรณีเดียวกันแนวคิดนามธรรม


21
ขอบคุณสำหรับคำอธิบายและขอขอบคุณสำหรับบทความประวัติย่อที่ไม่สมบูรณ์และไม่ถูกต้องส่วนใหญ่ของภาษาโปรแกรม ฉันคิดว่ามันอาจมาจากที่นั่น แท้จริงหนึ่งในอารมณ์ขันชิ้นที่ยิ่งใหญ่ที่สุดของการเขียนโปรแกรม
Roman A. Taycher

6
@ โจนาธาน: ในสูตรคลาสสิกของ monoid, ×หมายถึงผลิตภัณฑ์คาร์ทีเซียนของชุด คุณสามารถอ่านเพิ่มเติมเกี่ยวกับที่นี่: en.wikipedia.org/wiki/Cartesian_productแต่แนวคิดพื้นฐานคือว่าองค์ประกอบของS × Tคือคู่(s, t)ที่s ∈ SและT ∈ T ดังนั้นลายเซ็นของผลิตภัณฑ์ monoidal •: S × S -> Sในบริบทนี้ก็หมายถึงฟังก์ชั่นที่ใช้ 2 องค์ประกอบของSเป็นอินพุทและสร้างองค์ประกอบของเอสเป็นเอาท์พุท
Tom Crockett

12
@TahirHassan - ในทฤษฎีทั่วไปของหมวดหมู่เราจัดการกับ "วัตถุ" ทึบแสงแทนชุดและดังนั้นจึงไม่มีความคิดเบื้องต้นของ "องค์ประกอบ" แต่ถ้าคุณคิดเกี่ยวกับหมวดหมู่Setที่วัตถุถูกตั้งค่าและลูกศรเป็นฟังก์ชั่นองค์ประกอบของชุด S ใด ๆ ที่อยู่ในการติดต่อแบบหนึ่งต่อหนึ่งกับฟังก์ชั่นจากชุดองค์ประกอบหนึ่งไปยัง S นั่นคือสำหรับใด ๆ องค์ประกอบeของSมีฟังก์ชันหนึ่งฟังก์ชันf: 1 -> Sโดยที่1คือชุดองค์ประกอบหนึ่ง ... (ต่อ)
Tom Crockett

12
@TahirHassan ชุด 1 องค์ประกอบเป็นความเชี่ยวชาญของแนวคิดเชิงทฤษฎีหมวดหมู่ทั่วไปของ "วัตถุเทอร์มินัล": วัตถุเทอร์มินัลเป็นวัตถุของหมวดหมู่ที่มีลูกศรหนึ่งจากวัตถุอื่น ๆ ไปยังมัน (คุณสามารถตรวจสอบได้ว่า สิ่งนี้เป็นจริงของชุด 1 องค์ประกอบในชุด ) ในหมวดหมู่ทฤษฎีเทอร์มินัลวัตถุเรียกง่าย ๆ ว่า1 ; พวกมันมีลักษณะเฉพาะตัวจนถึงมอร์ฟิซึมดังนั้นจึงไม่มีประเด็นที่ทำให้พวกมันแตกต่าง ดังนั้นตอนนี้เรามีคำอธิบายหมวดหมู่ตามทฤษฎีอย่างหมดจดของ "องค์ประกอบของS " สำหรับS : ใด ๆพวกเขาเป็นเพียงลูกศรจาก1ถึงS !
Tom Crockett

7
@TahirHassan - หากต้องการใส่คำนี้ใน Haskell ให้คิดถึงข้อเท็จจริงที่ว่าถ้าSเป็นประเภทสิ่งที่คุณทำได้เมื่อเขียนฟังก์ชั่นf :: () -> Sก็คือเลือกประเภทของคำเฉพาะS("องค์ประกอบ" ของมันถ้าคุณต้องการ) และกลับมา มัน ... คุณไม่ได้รับข้อมูลจริงเกี่ยวกับการโต้แย้งดังนั้นจึงไม่มีวิธีที่จะเปลี่ยนแปลงพฤติกรรมของฟังก์ชัน ดังนั้นfจะต้องมีฟังก์ชั่นคงที่ซึ่งเพียงแค่คืนสิ่งเดิมทุกครั้ง ()("หน่วย") เป็นวัตถุเทอร์มินัลของหมวดหมู่Haskและมันไม่ใช่เรื่องบังเอิญว่ามีค่า 1 (ไม่แตกต่างกัน) ที่อาศัยอยู่
Tom Crockett

532

โดยสังหรณ์ใจฉันคิดว่าสิ่งที่คำศัพท์ทางคณิตศาสตร์แฟนซีพูดคือ:

หนังสือ

หนังสือคือชุดของวัตถุและวิธีการรวมพวกเขา monoids ที่รู้จักกันดีคือ:

  • ตัวเลขที่คุณสามารถเพิ่ม
  • รายการที่คุณสามารถต่อกันได้
  • ชุดคุณสามารถสหภาพ

มีตัวอย่างที่ซับซ้อนกว่านี้ด้วย

นอกจากนี้monoid ทุกตัวจะมีตัวตนซึ่งเป็นองค์ประกอบ "no-op" ที่ไม่มีผลเมื่อคุณรวมเข้ากับสิ่งอื่น:

  • 0 + 7 == 7 + 0 == 7
  • [] ++ [1,2,3] == [1,2,3] ++ [] == [1,2,3]
  • {} union {apple} == {apple} union {} == {apple}

ในที่สุด monoid ต้องเชื่อมโยงกัน (คุณสามารถลดชุดค่าผสมที่มีความยาวได้ตามที่คุณต้องการตราบใดที่คุณไม่เปลี่ยนลำดับจากซ้ายไปขวาของวัตถุ) การเพิ่มคือตกลง ((5 + 3) +1 == 5+ (3+ 1)) แต่การลบไม่ใช่ ((5-3) -1! = 5- (3-1))

monad

ทีนี้ลองพิจารณาชุดพิเศษชนิดและวิธีพิเศษในการรวมวัตถุ

วัตถุ

สมมติว่าชุดของคุณมีวัตถุชนิดพิเศษ: ฟังก์ชั่น และฟังก์ชั่นเหล่านี้มีลายเซ็นที่น่าสนใจ: พวกมันไม่ได้นำตัวเลขไปเป็นตัวเลข แต่ละฟังก์ชั่นจะใช้ตัวเลขเป็นรายการตัวเลขในกระบวนการสองขั้นตอนแทน

  1. คำนวณผลลัพธ์ 0 หรือมากกว่า
  2. รวมผลลัพธ์เหล่านั้นเข้ากับคำตอบเดียว

ตัวอย่าง:

  • 1 -> [1] (แค่ปิดอินพุต)
  • 1 -> [] (ยกเลิกอินพุตป้อนข้อมูลในรายการ)
  • 1 -> [2] (เพิ่ม 1 ลงในอินพุตและตัดผลลัพธ์)
  • 3 -> [4, 6] (เพิ่ม 1 ถึงอินพุตและคูณข้อมูลด้วย 2 และตัดผลลัพธ์หลายรายการ )

การรวมวัตถุ

นอกจากนี้วิธีการรวมฟังก์ชั่นของเราเป็นพิเศษ วิธีง่ายๆที่จะรวมฟังก์ชั่นเป็นองค์ประกอบ : ลองตัวอย่างข้างต้นของเราและเขียนแต่ละฟังก์ชั่นด้วยตัวเอง:

  • 1 -> [1] -> [[1]] (ปิดอินพุตสองครั้ง)
  • 1 -> [] -> [] (ทิ้งอินพุตห่อสิ่งที่ไม่มีในรายการสองครั้ง)
  • 1 -> [2] -> [UH-OH! ] (เราไม่สามารถ "เพิ่ม 1" ลงในรายการ! ")
  • 3 -> [4, 6] -> [UH-OH! ] (เราไม่สามารถเพิ่ม 1 รายการ!)

ประเด็นสำคัญคือคุณสามารถรวมจำนวนเต็มสองจำนวนเพื่อให้ได้จำนวนเต็ม แต่คุณไม่สามารถเขียนสองฟังก์ชันและรับฟังก์ชั่นประเภทเดียวกันได้เสมอ (ฟังก์ชั่นที่มีประเภท-> a จะเขียน แต่a-> [a]จะไม่ได้)

ดังนั้นขอนิยามวิธีที่แตกต่างของการรวมฟังก์ชั่น เมื่อเรารวมสองฟังก์ชั่นเหล่านี้เราไม่ต้องการที่จะ "ตัดสองครั้ง" ผลลัพธ์

นี่คือสิ่งที่เราทำ เมื่อเราต้องการรวมสองฟังก์ชั่น F และ G เราจะทำตามกระบวนการนี้ (เรียกว่าการผูก ):

  1. คำนวณ "ผลลัพธ์" จาก F แต่ไม่รวมเข้าด้วยกัน
  2. คำนวณผลลัพธ์จากการใช้ G กับผลลัพธ์แต่ละตัวของ F แยกกันโดยให้ผลลัพธ์เป็นชุดของการรวบรวมผลลัพธ์
  3. แผ่คอลเลกชัน 2 ระดับและรวมผลลัพธ์ทั้งหมด

กลับไปที่ตัวอย่างของเรามารวมฟังก์ชั่น (ผูก) เข้ากับตัวเองโดยใช้วิธีใหม่ของฟังก์ชั่น "การผูก":

  • 1 -> [1] -> [1] (ปิดอินพุตสองครั้ง)
  • 1 -> [] -> [] (ทิ้งอินพุตห่อสิ่งที่ไม่มีในรายการสองครั้ง)
  • 1 -> [2] -> [3] (เพิ่ม 1 จากนั้นเพิ่ม 1 อีกครั้งแล้วปิดผลลัพธ์)
  • 3 -> [4,6] -> [5,8,7,12] (เพิ่ม 1 ไปยังอินพุตและคูณด้วย 2 โดยเก็บผลลัพธ์ทั้งคู่จากนั้นทำทุกอย่างอีกครั้งเพื่อผลลัพธ์ทั้งสองแล้วจึงใส่คำสุดท้าย ผลลัพธ์ในรายการ)

วิธีการรวมฟังก์ชั่นที่ซับซ้อนมากขึ้นนี้คือการเชื่อมโยง (ต่อจากการรวมองค์ประกอบของฟังก์ชั่นเมื่อคุณไม่ได้ทำสิ่งห่อหุ้มแฟนซี)

ผูกมันทั้งหมดเข้าด้วยกัน

  • monad เป็นโครงสร้างที่กำหนดวิธีการรวมฟังก์ชัน (ผลลัพธ์ของ)
  • คล้ายกับว่า monoid เป็นโครงสร้างที่กำหนดวิธีการรวมวัตถุ
  • เมื่อวิธีการรวมกันเป็นแบบเชื่อมโยง
  • และที่ซึ่งมี 'No-op' พิเศษที่สามารถรวมกับบางสิ่งบางอย่างเพื่อส่งผลให้บางสิ่งไม่เปลี่ยนแปลง

หมายเหตุ

มีหลายวิธีในการ "ห่อ" ผลลัพธ์ คุณสามารถสร้างรายการหรือตั้งค่าหรือทิ้งทั้งหมดยกเว้นผลลัพธ์แรกในขณะที่สังเกตว่าไม่มีผลลัพธ์ให้แนบ sidecar of state พิมพ์ข้อความบันทึก ฯลฯ

ฉันเล่นหลวมเล็กน้อยกับคำจำกัดความโดยหวังว่าจะได้ความคิดที่สำคัญข้ามไปได้โดยสัญชาตญาณ

ฉันได้ง่ายสิ่งเล็กน้อยโดยยืนยันว่า monad ของเราดำเนินการในการทำงานประเภท-> [เป็น] ในความเป็นจริง monads ทำงานในฟังก์ชั่นของประเภท-> mbแต่การวางนัยทั่วไปเป็นรายละเอียดทางเทคนิคที่ไม่ใช่ความเข้าใจหลัก


22
นี่เป็นคำอธิบายที่ดีว่าแต่ละ monad ถือเป็นหมวดหมู่ได้อย่างไร ( หมวดKleisliเป็นสิ่งที่คุณแสดงให้เห็น - นอกจากนี้ยังมีหมวดหมู่ Eilenberg-Moore) แต่เนื่องจากความจริงที่ว่าคุณไม่สามารถเขียนใด ๆสองลูกศร Kleisli a -> [b]และc -> [d](คุณสามารถทำเช่นนี้หากb= c) นี้ไม่ได้ค่อนข้างอธิบายหนังสือ อันที่จริงแล้วมันคือการทำงานแบบแบนที่คุณอธิบายไว้แทนที่จะเป็นองค์ประกอบของฟังก์ชั่นซึ่งเป็น "ตัวดำเนินการโมโน"
Tom Crockett

6
ได้รับถ้าคุณ จำกัด monad ให้เป็นประเภทเดียวเท่านั้นคือถ้าคุณอนุญาตให้ลูกศร Kleisli ของแบบฟอร์มa -> [a]นี้จะเป็น monoid (เพราะคุณจะลดหมวดหมู่ Kleisli เป็นวัตถุเดียวและหมวดหมู่ของวัตถุเดียวเท่านั้น เป็นคำจำกัดความที่ monoid!) แต่มันจะไม่จับภาพทั่วไปของ monad
Tom Crockett

5
ในหมายเหตุล่าสุดมันช่วยให้จำได้ว่า -> [a] เป็นเพียงแค่ -> [] a ([] เป็นเพียงตัวสร้างประเภทด้วยเช่นกัน) ดังนั้นมันจึงไม่เพียงถูกมองว่าเป็น -> mb แต่ [] เป็นตัวอย่างของคลาส Monad
Evi1M4chine

8
นี่คือคำอธิบายที่ดีที่สุดและน่าสนใจที่สุดของ monads และภูมิหลังทางคณิตศาสตร์ของ monoids ที่ฉันได้เจอในสัปดาห์ที่แท้จริง นี่คือสิ่งที่ควรพิมพ์ในหนังสือ Haskell ทุกเล่มเมื่อพูดถึงพระ upvote! อาจได้รับข้อมูลเพิ่มเติมอีกต่อไปว่าพระสงฆ์ได้รับการตระหนักว่าเป็นอินสแตนซ์ประเภทของพารามิเตอร์ที่ล้อมรอบสิ่งที่ใส่ไว้ในฮาเซลลงในโพสต์ (อย่างน้อยนั่นคือวิธีที่ฉันเข้าใจพวกเขาในตอนนี้แก้ไขให้ฉันถ้าฉันผิดดูhaskell.org/haskellwiki/What_a_Monad_is_not )
sjas

1
นี่วิเศษมาก - เป็นคำอธิบายเดียวที่ฉันเข้าใจได้ดีพอที่จะอธิบายให้คนอื่นฟังได้ ... แต่ฉันก็ยังไม่เข้าใจว่าทำไมนี่จึงเป็นวิธีที่มีค่าในการคิดอะไร :(
Adam Barnes

84

อย่างแรกคือส่วนขยายและไลบรารีที่เราจะใช้:

{-# LANGUAGE RankNTypes, TypeOperators #-}

import Control.Monad (join)

ของเหล่านี้RankNTypesเป็นสิ่งเดียวที่จำเป็นอย่างยิ่งต่อไปนี้ ฉันเคยเขียนคำอธิบายRankNTypesว่าบางคนดูเหมือนจะมีประโยชน์ดังนั้นฉันจะพูดถึงสิ่งนั้น

การอ้างอิงคำตอบที่ยอดเยี่ยมของ Tom Crockettเรามี:

Monad คือ ...

  • endofunctor, T: X -> X
  • การเปลี่ยนแปลงตามธรรมชาติ, μ: T × T -> Tโดยที่×หมายถึงองค์ประกอบของ functor
  • การเปลี่ยนแปลงตามธรรมชาติη: I -> Tโดยที่ฉันเป็นตัวตนของ endofunctor บนX

... เป็นไปตามกฎหมายเหล่านี้:

  • μ (μ (T × T) × T)) = μ (T ×μ (T × T))
  • μ (η (T)) = T = μ (T (η))

เราจะแปลสิ่งนี้เป็นรหัส Haskell ได้อย่างไร เรามาเริ่มกันด้วยแนวคิดของการเปลี่ยนแปลงตามธรรมชาติ :

-- | A natural transformations between two 'Functor' instances.  Law:
--
-- > fmap f . eta g == eta g . fmap f
--
-- Neat fact: the type system actually guarantees this law.
--
newtype f :-> g =
    Natural { eta :: forall x. f x -> g x }

ชนิดของรูปแบบf :-> gคล้ายคลึงกับประเภทฟังก์ชั่น แต่แทนที่จะคิดว่ามันเป็นฟังก์ชั่นระหว่างสองประเภท (ประเภท*) คิดว่ามันเป็นซึ่มส์ระหว่างสองfunctors (แต่ละชนิด* -> *) ตัวอย่าง:

listToMaybe :: [] :-> Maybe
listToMaybe = Natural go
    where go [] = Nothing
          go (x:_) = Just x

maybeToList :: Maybe :-> []
maybeToList = Natural go
    where go Nothing = []
          go (Just x) = [x]

reverse' :: [] :-> []
reverse' = Natural reverse

โดยทั่วไปใน Haskell การแปลงโดยธรรมชาติคือฟังก์ชั่นจากบางประเภทf xเป็นอีกประเภทหนึ่งg xซึ่งxตัวแปรประเภทคือ "ไม่สามารถเข้าถึงได้" ไปยังผู้โทร ดังนั้นสำหรับตัวอย่างเช่นsort :: Ord a => [a] -> [a]ไม่สามารถทำในการเปลี่ยนแปลงทางธรรมชาติเพราะมันเป็น "จู้จี้จุกจิก" aเกี่ยวกับประเภทที่เราอาจจะยกตัวอย่างสำหรับ วิธีหนึ่งที่ใช้งานง่ายที่ฉันมักจะใช้ในการคิดสิ่งนี้คือ:

  • functor เป็นวิธีการในการดำเนินงานเกี่ยวกับการที่เนื้อหาของบางสิ่งบางอย่างโดยไม่ต้องสัมผัสโครงสร้าง
  • การเปลี่ยนแปลงทางธรรมชาติเป็นวิธีการดำเนินงานเกี่ยวกับการโครงสร้างของบางสิ่งบางอย่างได้โดยไม่ต้องสัมผัสหรือมองไปที่เนื้อหา

ทีนี้ถ้าอย่างนั้นเรามาจัดการกับส่วนคำจำกัดความกันเถอะ

ประโยคแรกคือ "endofunctor, T: X -> X. " Functorใน Haskell ทุกคนเป็น endofunctor ในสิ่งที่ผู้คนเรียกว่า "หมวด Hask" ซึ่งวัตถุประเภท Haskell (ชนิด*) และมี morphisms เป็นฟังก์ชัน Haskell ฟังดูเหมือนประโยคที่ซับซ้อน แต่จริงๆแล้วมันเป็นเรื่องเล็กน้อย ทั้งหมดหมายความว่าเป็นที่Functor f :: * -> *ให้คุณสร้างประเภทf a :: *สำหรับใด ๆa :: *และฟังก์ชั่นfmap f :: f a -> f bออกจากใด ๆf :: a -> bและสิ่งเหล่านี้เป็นไปตามกฎหมาย functor

ประโยคที่สอง: Identityfunctor ใน Haskell (ซึ่งมาพร้อมกับแพลตฟอร์มดังนั้นคุณสามารถนำเข้าได้) ถูกกำหนดด้วยวิธีนี้:

newtype Identity a = Identity { runIdentity :: a }

instance Functor Identity where
    fmap f (Identity a) = Identity (f a)

ดังนั้นการเปลี่ยนแปลงตามธรรมชาติη: I -> Tจากคำนิยามของ Tom Crockett สามารถเขียนได้ด้วยวิธีนี้Monadเช่นt:

return' :: Monad t => Identity :-> t
return' = Natural (return . runIdentity)

ประโยคที่สาม: องค์ประกอบของสองฟังก์ชั่นใน Haskell สามารถกำหนดได้ด้วยวิธีนี้ (ซึ่งมาพร้อมกับแพลตฟอร์ม):

newtype Compose f g a = Compose { getCompose :: f (g a) }

-- | The composition of two 'Functor's is also a 'Functor'.
instance (Functor f, Functor g) => Functor (Compose f g) where
    fmap f (Compose fga) = Compose (fmap (fmap f) fga)

ดังนั้นการแปลงตามธรรมชาติμ: T × T -> Tจากนิยามของ Tom Crockett สามารถเขียนได้ดังนี้:

join' :: Monad t => Compose t t :-> t
join' = Natural (join . getCompose)

คำแถลงว่านี่เป็น monoid ในหมวดหมู่ของ endofunctors นั้นหมายความว่าCompose(นำไปใช้เพียงบางส่วนกับพารามิเตอร์สองตัวแรก) นั้นคือการเชื่อมโยงและนั่นIdentityคือองค์ประกอบตัวตน คือว่ามอร์ฟอสมีมอร์ฟิซึ่มดังต่อไปนี้:

  • Compose f (Compose g h) ~= Compose (Compose f g) h
  • Compose f Identity ~= f
  • Compose Identity g ~= g

สิ่งเหล่านี้ง่ายต่อการพิสูจน์เพราะComposeและIdentityทั้งคู่ถูกกำหนดเป็นnewtypeและรายงาน Haskell กำหนดความหมายของnewtypeการเป็น isomorphism ระหว่างประเภทที่ถูกกำหนดและประเภทของการโต้แย้งไปยังตัวnewtypeสร้างข้อมูลของ ตัวอย่างเช่นลองพิสูจน์Compose f Identity ~= f:

Compose f Identity a
    ~= f (Identity a)                 -- newtype Compose f g a = Compose (f (g a))
    ~= f a                            -- newtype Identity a = Identity a
Q.E.D.

ในรูปแบบNaturalใหม่ฉันไม่สามารถเข้าใจได้ว่า(Functor f, Functor g)ข้อ จำกัด กำลังทำอะไร คุณอธิบายได้ไหม
dfeuer

@dfeuer มันไม่ได้ทำสิ่งที่จำเป็นจริงๆ
Luis Casillas

1
@LuisCasillas ฉันได้ลบFunctorข้อ จำกัดเหล่านั้นออกไปเพราะไม่จำเป็น หากคุณไม่เห็นด้วยก็สามารถเพิ่มกลับได้
แลมบ์ดาแฟรี่

คุณสามารถอธิบายรายละเอียดเกี่ยวกับความหมายอย่างเป็นทางการสำหรับผลิตภัณฑ์ของ functors ที่จะใช้เป็นองค์ประกอบได้หรือไม่? โดยเฉพาะอย่างยิ่งการประมาณค่า morphisms สำหรับการจัดองค์ประกอบของ functor คืออะไร? ฉันเดาว่าผลิตภัณฑ์นี้ถูกกำหนดไว้สำหรับ functor F กับตัวเองเท่านั้น, F x F และเฉพาะเมื่อjoinมีการกำหนดไว้ และนั่นjoinคือมอร์ฟิซึ่มประมาณการ แต่ฉันไม่แน่ใจ.
tksfz

6

หมายเหตุ:ไม่นี่ไม่เป็นความจริง เมื่อถึงจุดหนึ่งก็มีความคิดเห็นเกี่ยวกับคำตอบนี้จากแดน Piponi ตัวเองบอกว่าสาเหตุและผลที่นี่ตรงข้ามแน่นอนว่าเขาเขียนบทความของเขาในการตอบสนอง quip ของ James Iry แต่ดูเหมือนว่ามันจะถูกลบออกบางทีอาจจะเป็นความคิดที่เป็นระเบียบ

ด้านล่างคือคำตอบเดิมของฉัน


มันค่อนข้างเป็นไปได้ที่ Iry ได้อ่านจาก Monoids ถึง Monadsซึ่งเป็นตำแหน่งที่ Dan Piponi (sigfpe) สร้าง monads จาก monoids ใน Haskell ด้วยการอภิปรายอย่างมากเกี่ยวกับทฤษฎีหมวดหมู่และกล่าวถึง "หมวดหมู่ของ endofunctors on Hask " ไม่ว่าในกรณีใดก็ตามใครก็ตามที่สงสัยว่าการที่ monad เป็น monoid ในประเภทของ endofunctors อาจได้ประโยชน์จากการอ่านที่มานี้


1
"บางทีบาง tidier บังคับ" - :-)หรือเป็นเราด้วยความรักหมายถึงพวกเขาในเว็บไซต์นี้เป็นผู้ดูแล
halfer

6

ผมมาโพสต์นี้โดยวิธีการที่ดีกว่าการทำความเข้าใจการอนุมานของคำพูดที่น่าอับอายจากเครื่อง Mac เลนของทฤษฎีหมวดหมู่สำหรับนักคณิตศาสตร์ทำงาน

ในการอธิบายสิ่งที่เป็นสิ่งที่มักจะมีประโยชน์เท่าเทียมกันเพื่ออธิบายสิ่งที่ไม่

ข้อเท็จจริงที่ว่า Mac Lane ใช้คำอธิบายเพื่ออธิบาย Monad หนึ่งอาจบ่งบอกว่ามันอธิบายบางสิ่งบางอย่างที่ไม่ซ้ำกับ monads อดทนกับฉัน เพื่อพัฒนาความเข้าใจที่กว้างขึ้นเกี่ยวกับคำแถลงนี้ผมเชื่อว่ามันต้องชัดเจนว่าเขาไม่ได้อธิบายสิ่งที่เป็นเอกลักษณ์ของพระสงฆ์ ข้อความนี้อธิบายถึงการใช้งานและลูกศรอย่างเท่าเทียมกัน ด้วยเหตุผลเดียวกันเราสามารถมี monoids สองตัวบน Int (Sum และ Product) เราสามารถมี monoids หลายตัวบน X ในหมวดหมู่ของ endofunctors แต่มีความคล้ายคลึงกันมากขึ้น

ทั้ง Monad และ Applicative ตรงตามเกณฑ์:

  • endo => ลูกศรหรือมอร์ฟิซึ่มส์ที่เริ่มต้นและสิ้นสุดในที่เดียวกัน
  • functor => ลูกศรหรือ morphism ระหว่างสองหมวดหมู่

    (เช่นในแต่ละวันTree a -> List bแต่ในหมวดหมู่Tree -> List)

  • monoid => วัตถุเดี่ยว; เช่นชนิดเดียว แต่ในบริบทนี้เฉพาะที่เกี่ยวกับเลเยอร์ภายนอก ดังนั้นเราไม่สามารถมีเพียงTree -> ListList -> List

คำสั่งใช้ "หมวดหมู่ของ ... " ซึ่งจะกำหนดขอบเขตของคำสั่ง เป็นตัวอย่างที่ Functor หมวดหมู่อธิบายขอบเขตของf * -> g *เช่นAny functor -> Any functorเช่นหรือ Tree * -> List *Tree * -> Tree *

สิ่งที่เป็นคำสั่งเด็ดขาดไม่ได้ระบุอธิบายที่ทุกอย่างจะได้รับอนุญาต

ในกรณีนี้ภายใน functors ที่* -> *รู้จักกันในชื่อไม่ได้ระบุซึ่งหมายความว่าa -> b Anything -> Anything including Anything elseในฐานะที่เป็นจินตนาการของฉันกระโดดไป Int -> String ก็ยังมีInteger -> Maybe Intหรือแม้กระทั่งที่ Maybe Double -> Either String Inta :: Maybe Double; b :: Either String Int

ดังนั้นคำสั่งมารวมกันดังนี้:

  • ขอบเขต functor :: f a -> g b(เช่นชนิดใด ๆ ที่กำหนดพารามิเตอร์เป็นชนิดที่กำหนดพารามิเตอร์ใด ๆ )
  • endo + functor :: f a -> f b(กล่าวคือประเภทใด ๆ ที่กำหนดพารามิเตอร์ชนิดที่ปรับพารามิเตอร์เดียวกัน) ... กล่าวว่าแตกต่างกัน
  • monoid ในหมวดหมู่ของ endofunctor

แล้วพลังของสิ่งก่อสร้างนี้อยู่ที่ไหน? เพื่อชื่นชมการเปลี่ยนแปลงเต็มรูปแบบฉันต้องเห็นว่าภาพวาดทั่วไปของ monoid (วัตถุเดียวที่มีลักษณะเหมือนลูกศรเอกลักษณ์:: single object -> single object) ล้มเหลวในการแสดงให้เห็นว่าฉันได้รับอนุญาตให้ใช้ลูกศรที่กำหนดพารามิเตอร์ด้วยค่า monoid จำนวนเท่าใดก็ได้จากวัตถุประเภทเดียวที่ได้รับอนุญาตใน Monoid endo, ~ identity arrow definition ของความเท่าเทียมกันจะละเว้นค่าประเภทของ functor และทั้งประเภทและค่าของเลเยอร์ "payload" ที่อยู่ด้านในสุด ดังนั้นความเท่าเทียมจะส่งกลับtrueในทุกสถานการณ์ที่ประเภท functorial ตรงกัน (เช่นNothing -> Just * -> Nothingเทียบเท่าJust * -> Just * -> Just *เพราะทั้งคู่Maybe -> Maybe -> Maybe)

แถบด้านข้าง: ~ นอกเป็นแนวความคิด f aแต่ด้านซ้ายสัญลักษณ์มากที่สุดใน นอกจากนี้ยังอธิบายถึงสิ่งที่ "Haskell" อ่านในครั้งแรก (ภาพใหญ่); ดังนั้น Type คือ "ภายนอก" ที่สัมพันธ์กับ Value Type ความสัมพันธ์ระหว่างเลเยอร์ (สายการอ้างอิง) ในการเขียนโปรแกรมไม่ใช่เรื่องง่ายที่จะเกี่ยวข้องในหมวดหมู่ หมวดหมู่ชุดใช้เพื่ออธิบายประเภท (Int, Strings, บางที Int ฯลฯ ) ซึ่งรวมถึงหมวดหมู่ของ Functor (ประเภทพารามิเตอร์) ห่วงโซ่การอ้างอิง: ประเภทของ Functor, ค่าของ Functor (องค์ประกอบของชุดของ Functor นั้น, เช่น Nothing, Just) และในทางกลับกันทุกอย่างอื่นที่แต่ละค่าของ functor ชี้ไป ในหมวดหมู่ความสัมพันธ์นั้นถูกอธิบายแตกต่างกันเช่นreturn :: a -> m aถือเป็นการเปลี่ยนแปลงตามธรรมชาติจาก Functor หนึ่งไปยัง Functor อื่นซึ่งแตกต่างจากสิ่งที่กล่าวถึงในตอนนี้

กลับไปที่เธรดหลักทั้งหมดสำหรับผลิตภัณฑ์เทนเซอร์ที่กำหนดไว้ใด ๆ และค่าที่เป็นกลางคำแถลงนี้อธิบายถึงโครงสร้างการคำนวณที่ทรงพลังอย่างน่าอัศจรรย์ที่เกิดจากโครงสร้างที่ขัดแย้งกัน:

  • ด้านนอกจะปรากฏเป็นวัตถุชิ้นเดียว (เช่น, :: List); คงที่
  • แต่ภายในอนุญาตให้มีการเปลี่ยนแปลงมากมาย
    • จำนวนของค่าชนิดเดียวกันใด ๆ (เช่น Empty | ~ NonEmpty) เป็นค่าอาหารสัตว์ไปยังฟังก์ชันของ arity ใด ๆ ผลิตภัณฑ์เทนเซอร์จะลดจำนวนอินพุตใด ๆ ให้เป็นค่าเดียว ... สำหรับเลเยอร์ภายนอก (~ foldที่ไม่ได้บอกอะไรเลยเกี่ยวกับเพย์โหลด)
    • ช่วงไม่สิ้นสุดของทั้งประเภทและค่าสำหรับเลเยอร์ส่วนใหญ่ภายใน

ใน Haskell การชี้แจงความเกี่ยวข้องของข้อความเป็นสิ่งสำคัญ อำนาจและความเก่งกาจของโครงสร้างนี้มีอะไรอย่างจะทำอย่างไรกับ monad ต่อ se กล่าวอีกนัยหนึ่งการสร้างไม่ได้ขึ้นอยู่กับสิ่งที่ทำให้ Monad มีความโดดเด่น

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

นี่มักจะเข้าใจผิด คำแถลงยังอธิบายต่อไปว่าjoin :: m (m a) -> m aเป็นผลิตภัณฑ์เทนเซอร์สำหรับเอนโดโฟนตัวเดียว อย่างไรก็ตามมันไม่ได้อธิบายว่าในบริบทของคำแถลง(<*>)นี้ได้รับการเลือกเช่นกันอย่างไร มันเป็นตัวอย่างของหก / ครึ่งโหลอย่างแท้จริง ตรรกะสำหรับการรวมค่านั้นเหมือนกันหมด อินพุตเดียวกันสร้างเอาต์พุตเดียวกันจากแต่ละรายการ (ซึ่งแตกต่างจากผลรวม Sum และ Product สำหรับ Int เพราะจะสร้างผลลัพธ์ที่แตกต่างเมื่อรวม Ints)

ดังนั้นเพื่อสรุป: monoid ในหมวดหมู่ของ endofunctors อธิบาย:

   ~t :: m * -> m * -> m *
   and a neutral value for m *

(<*>)และ(>>=)ให้การเข้าถึงสองmค่าพร้อมกันเพื่อคำนวณค่าส่งคืนเดียว ตรรกะที่ใช้ในการคำนวณค่าส่งคืนเหมือนกันทุกประการ หากไม่ใช่สำหรับรูปร่างที่แตกต่างกันของฟังก์ชั่นที่พวกเขาแปร ( f :: a -> bและk :: a -> m b) และตำแหน่งของพารามิเตอร์ที่มีประเภทการคำนวณแบบส่งคืนเดียวกัน (เช่นa -> b -> bเมื่อเทียบกับb -> a -> bสำหรับแต่ละลำดับ) ฉันสงสัยว่าเราจะได้แปรพารามิเตอร์ตรรกะตรรกะ ผลิตภัณฑ์เทนเซอร์สำหรับนำมาใช้ใหม่ในทั้งสองคำจำกัดความ เป็นแบบฝึกหัดที่จะทำให้ประเด็นลองและนำไปใช้~tและคุณจะจบลงด้วย(<*>)และ(>>=)ขึ้นอยู่กับว่าคุณตัดสินใจกำหนดมันforall a bอย่างไร

หากจุดสุดท้ายของฉันเป็นอย่างน้อยที่สุดจริงแนวคิดมันก็จะอธิบายความแตกต่างที่แม่นยำและเฉพาะการคำนวณระหว่างการใช้งานและ Monad: ฟังก์ชั่นที่พวกเขาแปรปรวน ในคำอื่น ๆ คือความแตกต่างภายนอกในการดำเนินการของการเรียนประเภทเหล่านี้

โดยสรุปจากประสบการณ์ของฉันเองคำพูดที่น่าอับอายของ Mac Lane ได้ให้คำแนะนำ "goto" meme ที่ดีซึ่งเป็นป้ายบอกทางให้ฉันอ้างอิงขณะนำทางผ่านหมวดของฉันเพื่อทำความเข้าใจสำนวนที่ใช้ใน Haskell ให้ดีขึ้น มันประสบความสำเร็จในการบันทึกขอบเขตของความสามารถในการคำนวณที่มีประสิทธิภาพซึ่งทำให้สามารถเข้าถึงได้อย่างมหัศจรรย์ใน Haskell

อย่างไรก็ตามมีประชดในวิธีที่ฉันเข้าใจผิดครั้งแรกการบังคับใช้คำสั่งที่นอกเหนือจาก monad และสิ่งที่ฉันหวังว่าถ่ายทอดที่นี่ ทุกสิ่งที่อธิบายจะกลายเป็นสิ่งที่คล้ายกันระหว่าง Applicative และ Monads (และ Arrows ท่ามกลางคนอื่น ๆ ) สิ่งที่ไม่ได้กล่าวคือความแตกต่างเล็ก ๆ แต่มีประโยชน์อย่างแม่นยำ

- จ


5

คำตอบที่นี่ทำงานได้อย่างยอดเยี่ยมในการกำหนดทั้ง monoids และ monads อย่างไรก็ตามพวกเขายังดูเหมือนจะไม่ตอบคำถาม:

และในบันทึกย่อที่สำคัญน้อยกว่านี่คือความจริงและถ้าเป็นเช่นนั้นคุณสามารถให้คำอธิบายได้ (หวังว่าจะมีคนที่ไม่เข้าใจประสบการณ์ของ Haskell มาก)

ประเด็นสำคัญของสิ่งที่ขาดหายไปที่นี่คือแนวคิดที่แตกต่างกันของ "monoid" การจำแนกประเภทที่เรียกว่าแม่นยำยิ่งขึ้น - หนึ่งของ monoid ในหมวดหมู่ monoidal หนังสือของ Sadly Mac Lane นั้นทำให้เกิดความสับสน :

ทั้งหมดบอกว่า monad ในXเป็นเพียง monoid ในหมวดหมู่ของ endofunctors ของXด้วยผลิตภัณฑ์ที่×ถูกแทนที่ด้วยองค์ประกอบของ endofunctors และหน่วยที่กำหนดโดย endofunctor ตัวตน

ความสับสนหลัก

ทำไมถึงสับสน? เพราะมันไม่ได้กำหนดว่าอะไรคือ "หนังสือในหมวดหมู่ของ endofunctors ว่า" Xของ แต่ประโยคนี้แสดงให้เห็นว่ามีการสร้าง monoid ภายในชุดของ endofunctors ทั้งหมดพร้อมกับการจัดองค์ประกอบของ functor เป็นการดำเนินการแบบไบนารี่ ซึ่งทำงานได้ดีอย่างสมบูรณ์แบบและเปลี่ยนเป็น monoid ส่วนย่อยของ endofunctors ใด ๆ ที่มี functor ตัวตนและถูกปิดภายใต้องค์ประกอบ functor

แต่นี่ไม่ใช่การตีความที่ถูกต้องซึ่งหนังสือไม่สามารถอธิบายได้อย่างชัดเจนในขั้นตอนนั้น Monad fเป็นendofunctor คงที่ไม่ใช่เซตย่อยของ endofunctors ที่ปิดภายใต้การจัดองค์ประกอบ การสร้างร่วมกันคือการใช้fเพื่อสร้างหนังสือโดยการตั้งค่าของทุกkองค์ประกอบเท่าf^k = f(f(...))ของfด้วยตัวเองรวมทั้งสอดคล้องกับตัวตนที่k=0 f^0 = idและตอนนี้ชุดSของพลังทั้งหมดเหล่านี้สำหรับทุกคนk>=0ย่อมเป็น monoid "กับผลิตภัณฑ์×แทนที่ด้วยองค์ประกอบของ endofunctors และหน่วยที่กำหนดโดย endofunctor เอกลักษณ์"

และยัง:

  • หนังสือนี้Sสามารถกำหนดสำหรับ functor ใด ๆfหรือแม้กระทั่งตัวอักษรสำหรับการใด ๆ Xด้วยตนเองแผนที่ของ fมันเป็นหนังสือที่สร้างขึ้นโดย
  • โครงสร้าง monoidal ที่Sกำหนดโดยองค์ประกอบ functor และ functor เอกลักษณ์ไม่มีอะไรเกี่ยวข้องกับfการเป็นหรือไม่เป็น monad

และเพื่อให้สิ่งที่มากขึ้นทำให้เกิดความสับสนความหมายของ "หนังสือในหมวดหมู่ monoidal" มาต่อมาในหนังสือที่คุณสามารถดูจากตารางของเนื้อหา และยังเข้าใจความคิดนี้เป็นสิ่งสำคัญอย่างยิ่งที่จะเข้าใจการเชื่อมต่อกับพระ

หมวดหมู่ monoidal (เข้มงวด)

ไปบทที่เจ็ดใน Monoids (ที่มาช้ากว่าบทที่หกบน Monads) เราจะพบความหมายของสิ่งที่เรียกว่าหมวดหมู่ monoidal เข้มงวดเป็นสาม(B, *, e)ที่Bเป็นหมวดหมู่, bifunctor (functor ที่เกี่ยวกับส่วนประกอบแต่ละคนมีองค์ประกอบอื่น ๆ คงที่ ) และเป็นวัตถุหน่วยในการตอบสนองความสัมพันธ์และกฎหมายหน่วย:*: B x B-> BeB

(a * b) * c = a * (b * c)
a * e = e * a = a

สำหรับวัตถุใด ๆa,b,cของBและอัตลักษณ์เดียวกัน morphisms ใด ๆa,b,cกับการeแทนที่ด้วยการซึ่มส์ตัวตนของid_e eขณะนี้เป็นคำแนะนำให้สังเกตว่าในกรณีที่เราสนใจซึ่งBเป็นประเภทของ endofunctors ของXกับการเปลี่ยนแปลงตามธรรมชาติเป็น morphisms *องค์ประกอบ functor และefunctor ตัวตนกฎหมายเหล่านี้มีความพึงพอใจทั้งหมดที่สามารถตรวจสอบได้โดยตรง

สิ่งที่เกิดขึ้นภายหลังในหนังสือเล่มนี้คือคำจำกัดความของหมวดหมู่ "ผ่อนคลาย" ซึ่งมีเพียงโมดูโล่ที่มีการเปลี่ยนแปลงตามธรรมชาติบางอย่างที่น่าพอใจซึ่งเรียกว่าความสัมพันธ์ที่เชื่อมโยงกันซึ่งไม่สำคัญสำหรับกรณีของเราในหมวดหมู่ endofunctor

Monoids ในประเภท monoidal

สุดท้ายในส่วนที่ 3 "Monoids" ของบทที่ VII คำจำกัดความที่แท้จริงได้รับ:

monoid cในประเภท monoidal (B, *, e)เป็นวัตถุที่Bมีลูกศรสองอัน (morphisms)

mu: c * c -> c
nu: e -> c

ทำให้ 3 แผนภาพสับเปลี่ยน จำได้ว่าในกรณีของเราเหล่านี้เป็น morphisms ในหมวดหมู่ของ endofunctors ซึ่งเป็นการเปลี่ยนแปลงตามธรรมชาติที่สอดคล้องกับแม่นยำjoinและreturnสำหรับ monad การเชื่อมต่อจะชัดเจนยิ่งขึ้นเมื่อเราทำให้การจัดองค์ประกอบ*ชัดเจนมากขึ้นแทนที่c * cด้วยmonad ของเราอยู่c^2ที่ไหนc

ในที่สุดสังเกตว่า 3 ไดอะแกรมสลับสับเปลี่ยน (ในคำจำกัดความของ monoid ในหมวดหมู่ monoidal) เขียนสำหรับหมวดหมู่ monoidal ทั่วไป (ไม่เข้มงวด) ในขณะที่ในกรณีของเราการเปลี่ยนแปลงตามธรรมชาติทั้งหมดที่เกิดขึ้นเป็นส่วนหนึ่งของหมวดหมู่ monoidal นั่นจะทำให้ไดอะแกรมเหมือนกับที่อยู่ในคำจำกัดความของ monad ทำให้การติดต่อทางจดหมายเสร็จสมบูรณ์

ข้อสรุป

ในการสรุป monad ใด ๆ ที่เป็นโดยความหมาย endofunctor ดังนั้นวัตถุที่อยู่ในหมวดหมู่ของ endofunctors ที่ที่เอกjoinและreturnผู้ประกอบการตอบสนองความหมายของหนังสือในเฉพาะ (เข้มงวด) หมวด ในทางกลับกัน monoid ใด ๆ ในหมวดหมู่ monoidal ของ endofunctors โดยนิยามสาม(c, mu, nu)ประกอบด้วยวัตถุและลูกศรสองลูกเช่นการเปลี่ยนแปลงตามธรรมชาติในกรณีของเราพอใจกฎหมายเดียวกันกับ monad

ในที่สุดให้สังเกตความแตกต่างที่สำคัญระหว่าง monoids (แบบคลาสสิก) และ monoids ทั่วไปในหมวดหมู่ monoidal ทั้งสองลูกศรmuและnuข้างต้นไม่ได้อีกต่อไปดำเนินการทวิภาคและหน่วยในชุด แต่คุณมีหนึ่ง cendofunctor องค์ประกอบนักแต่งเพลง*และนักแสดงตัวตนเพียงอย่างเดียวไม่ได้จัดเตรียมโครงสร้างที่สมบูรณ์ที่จำเป็นสำหรับ monad แม้จะมีคำพูดที่สับสนในหนังสือ

อีกวิธีหนึ่งที่จะเปรียบเทียบกับหนังสือมาตรฐานCของทุกแผนที่ตนเองของชุดAที่ดำเนินการทวิภาคเป็นองค์ประกอบที่สามารถมองเห็นไปยังแผนที่ผลิตภัณฑ์คาร์ทีเซียนมาตรฐานเข้าไปC x C Cผ่านไปยังหมวดหมู่ monoid เรากำลังเปลี่ยนผลิตภัณฑ์ cartesian xด้วยองค์ประกอบ functor *และการดำเนินการแบบไบนารีจะถูกแทนที่ด้วยการแปลงตามธรรมชาติmuจาก c * cไปcเป็นนั่นคือชุดของjoinผู้ประกอบการ

join: c(c(T))->c(T)

สำหรับวัตถุทุกTชนิด (พิมพ์โปรแกรม) และองค์ประกอบประจำตัวใน monoids แบบคลาสสิกซึ่งสามารถระบุด้วยภาพของแผนที่จากจุดหนึ่งจุดคงที่ได้รับการแทนที่ด้วยคอลเลกชันของreturnผู้ประกอบการ

return: T->c(T) 

แต่ตอนนี้ไม่มีผลิตภัณฑ์คาร์ทีเซียนอีกต่อไปดังนั้นจึงไม่มีคู่ขององค์ประกอบและจึงไม่มีการดำเนินการแบบไบนารี


ดังนั้นคำตอบของคุณในส่วน "เป็นจริง" คืออะไร? เป็นความจริงหรือไม่ว่า monad เป็น monoid ในประเภทของ endofunctors? และถ้าใช่ความสัมพันธ์ระหว่างแนวคิดทฤษฎีหมวดหมู่ของ monoid และ algebraic monoid (ชุดที่มีการคูณการเชื่อมโยงและหน่วย) คืออะไร
Alexander Belopolsky
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.