Monads ฟรีคืออะไร


368

ผมเคยเห็นในระยะฟรี Monadปรากฏขึ้นทุก ขณะนี้ และ จากนั้นบางครั้ง แต่ทุกคนก็ดูเหมือนว่าจะใช้ / หารือเกี่ยวกับพวกเขาโดยไม่ให้คำอธิบายเกี่ยวกับสิ่งที่พวกเขาเป็น ดังนั้นพระอะไรบ้าง (ฉันว่าฉันคุ้นเคยกับ monads และพื้นฐานของ Haskell แต่มีเพียงความรู้คร่าวๆเกี่ยวกับทฤษฎีหมวดหมู่)


12
คำอธิบายที่ดีพอสมควรอยู่ที่นี่haskellforall.com/2012/06/…
Roger Lindsjö

19
@Roger หน้าเว็บที่นำฉันมาที่นี่ สำหรับฉันตัวอย่างนั้นกำหนดอินสแตนซ์ monad สำหรับประเภทที่ชื่อว่า "ฟรี" และนั่นคือมัน
David

คำตอบ:


295

คำตอบของ Edward Kmett นั้นยอดเยี่ยมมาก แต่มันเป็นเทคนิคเล็กน้อย นี่คือคำอธิบายที่เข้าถึงได้ง่ายขึ้น

พระฟรีเป็นเพียงวิธีการทั่วไปในการเปลี่ยนฟังก์ชั่นเป็นพระ นั่นคือการให้ functor ใด ๆ ที่f Free fเป็น Monad สิ่งนี้จะไม่มีประโยชน์มากยกเว้นคุณจะได้รับฟังก์ชั่น

liftFree :: Functor f => f a -> Free f a
foldFree :: Functor f => (f r -> r) -> Free f r -> r

ครั้งแรกของเหล่านี้ช่วยให้คุณ "เข้าสู่" monad ของคุณและคนที่สองให้วิธีที่จะ "ออกไป" ของมัน

โดยทั่วไปแล้วหาก X คือ Y ที่มีสิ่งพิเศษ P อยู่ดังนั้น "free X" จึงเป็นวิธีที่จะได้รับจาก Y เป็น X โดยไม่ได้รับอะไรพิเศษ

ตัวอย่าง: monoid (X) คือ set (Y) ที่มีโครงสร้างพิเศษ (P) ที่โดยทั่วไปบอกว่ามันมีการดำเนินการ (คุณสามารถคิดเพิ่มเติม) และตัวตนบางอย่าง (เช่นศูนย์)

ดังนั้น

class Monoid m where
   mempty  :: m
   mappend :: m -> m -> m

ตอนนี้เราทุกคนรู้รายการ

data [a] = [] | a : [a]

เอาtล่ะเรารู้ว่า[t]มันเป็นแบบโมโน

instance Monoid [t] where
  mempty   = []
  mappend = (++)

และรายการนั้นเป็น "monoid ฟรี" มากกว่าชุด (หรือในประเภท Haskell)

เอาล่ะพระฟรีจึงเป็นแนวคิดเดียวกัน เรารับนักแสดงนำและส่ง Monad ในความเป็นจริงเนื่องจาก monads สามารถมองเห็นเป็น monoids ในหมวดหมู่ของ endofunctors ความหมายของรายการ

data [a] = [] | a : [a]

ดูเหมือนความหมายของ monads ฟรี

data Free f a = Pure a | Roll (f (Free f a))

และMonadอินสแตนซ์นั้นมีความคล้ายคลึงกับMonoidอินสแตนซ์ของรายการ

--it needs to be a functor
instance Functor f => Functor (Free f) where
  fmap f (Pure a) = Pure (f a)
  fmap f (Roll x) = Roll (fmap (fmap f) x)

--this is the same thing as (++) basically
concatFree :: Functor f => Free f (Free f a) -> Free f a
concatFree (Pure x) = x
concatFree (Roll y) = Roll (fmap concatFree y)

instance Functor f => Monad (Free f) where
  return = Pure -- just like []
  x >>= f = concatFree (fmap f x)  --this is the standard concatMap definition of bind

ตอนนี้เราได้งานสองอย่างแล้ว

-- this is essentially the same as \x -> [x]
liftFree :: Functor f => f a -> Free f a
liftFree x = Roll (fmap Pure x)

-- this is essentially the same as folding a list
foldFree :: Functor f => (f r -> r) -> Free f r -> r
foldFree _ (Pure a) = a
foldFree f (Roll x) = f (fmap (foldFree f) x)

12
นี่อาจเป็นคำอธิบายที่เข้าถึงได้ง่ายที่สุดของ "ฟรี" ที่ฉันเคยเห็น โดยเฉพาะย่อหน้าที่ขึ้นต้นด้วย "มากกว่าปกติ"
John L

16
ฉันคิดว่ามันน่าสนใจที่จะดูFree f a = Pure a | Roll (f (Free f a))ว่าFree f a = a + fa + ffa + ..."นำไปใช้กับหลาย ๆ ครั้ง" จากนั้นconcatFree(เช่นjoin) ใช้ "f นำจำนวนครั้งใด ๆ ไปใช้ (f ใช้จำนวนครั้งใดก็ได้กับ a)" และยุบแอปพลิเคชันที่ซ้อนกันสองรายการไว้ในที่เดียว และ>>=ใช้ "f ใช้จำนวนครั้งใด ๆ กับ" และ "วิธีการได้รับจาก a ถึง (b กับ f นำไปใช้จำนวนครั้งใด ๆ )" และโดยทั่วไปจะใช้หลังกับของในอดีตและยุบรัง ตอนนี้ฉันเองก็เข้าใจแล้ว!
jkff

1
เป็นconcatFreeพื้นjoin?
rgrinberg

11
“ นี่เป็นคำอธิบายที่เข้าถึงได้ง่ายขึ้น […] ในความเป็นจริงเนื่องจาก monads สามารถมองเห็นเป็น monoids ในหมวดหมู่ของ endo functors, …” อย่างไรก็ตามฉันคิดว่านี่เป็นคำตอบที่ดีมาก
Ruud

2
"monads สามารถมองเห็นเป็น monoids ในหมวดหมู่ของ functors Endo ว่า" <3 (คุณควรเชื่อมโยงไปstackoverflow.com/a/3870310/1306877เพราะทุก haskeller ควรรู้เกี่ยวกับการอ้างอิงที่!)
TLO

418

ต่อไปนี้เป็นคำตอบที่ง่ายยิ่งขึ้น: Monad เป็นสิ่งที่ "คำนวณ" เมื่อบริบทของ monadic ถูกยุบโดยjoin :: m (m a) -> m a(เรียกคืนได้ว่า>>=สามารถกำหนดเป็นx >>= y = join (fmap y x)) นี่คือวิธีที่ Monads นำบริบทผ่านสายการคำนวณตามลำดับเนื่องจากแต่ละจุดในชุดบริบทบริบทจากการโทรก่อนหน้านี้จะถูกยุบด้วยการถัดไป

ฟรี monadตอบสนองทุกกฎหมาย Monad แต่ไม่ได้ดำเนินการใด ๆ ยุบ (เช่นการคำนวณ) มันเพิ่งสร้างชุดบริบทที่ซ้อนกัน ผู้ใช้ที่สร้างค่า monadic ฟรีนั้นรับผิดชอบในการทำบางสิ่งบางอย่างกับบริบทที่ซ้อนกันดังนั้นความหมายขององค์ประกอบดังกล่าวสามารถรอการตัดบัญชีได้จนกว่าจะมีการสร้างค่า monadic ขึ้น


8
ย่อหน้าของคุณเป็นส่วนเสริมที่ดีมากสำหรับโพสต์ของฟิลิป
David

20
ฉันชอบคำตอบนี้จริงๆ
danidiaz

5
Monad ฟรีสามารถแทนที่คลาสชนิด Monad ได้หรือไม่? นั่นคือฉันสามารถเขียนโปรแกรมโดยใช้เพียงการส่งคืนและผูกของ monad ฟรีจากนั้นเข้าร่วมผลลัพธ์โดยใช้อย่างใดอย่างหนึ่งที่ฉันชอบของ Mwybe หรือ List หรืออะไรก็ตามหรือแม้แต่สร้างมุมมอง monadic หลายครั้งในการเรียกใช้ฟังก์ชัน ไม่สนใจด้านล่างและไม่สิ้นสุดนั่นคือ
misterbee

2
คำตอบนี้จะช่วย แต่ฉันคิดว่ามันจะสับสนฉันได้ฉันไม่ได้พบ 'ร่วม' ใน NICTA แน่นอนและอ่านhaskellforall.com/2012/06/... ดังนั้นสำหรับฉันเคล็ดลับในการทำความเข้าใจคือการอ่านคำตอบมากมายจนกว่ามันจะจมลงไป (อ้างอิง NICTA: github.com/NICTA/course/blob/master/src/Course/Bind.hs )
Martin Capodici

1
คำตอบนี้ดีที่สุดตลอดกาล
Curycu

142

ฟูฟรีเกิดขึ้นเป็นสิ่งที่ง่ายที่สุดที่เป็นไปตามกฎหมาย 'ฟู' ทั้งหมด กล่าวคือมันเป็นไปตามกฎหมายที่จำเป็นในการเป็นฟูและไม่มีอะไรพิเศษ

functor ที่หลงลืมนั้นเป็นส่วนหนึ่งที่ "ลืม" ส่วนหนึ่งของโครงสร้างเมื่อมันเปลี่ยนจากหมวดหมู่หนึ่งไปอีกหมวดหนึ่ง

ได้รับ functors F : D -> CและG : C -> DเราบอกF -| G, Fเป็น adjoint ซ้ายGหรือGเป็น adjoint สิทธิที่จะFเมื่อใดก็ตามที่ forall A, B: F a -> bเป็น isomorphic ไปa -> G bที่ลูกศรมาจากประเภทที่เหมาะสม

อย่างเป็นทางการนัก functor ฟรีเหลือ adjoint กับ functor ลืม

ฟรี Monoid

ให้เราเริ่มต้นด้วยตัวอย่างที่ง่ายกว่าคือโมโนฟรี

ใช้หนังสือซึ่งถูกกำหนดโดยชุดผู้ให้บริการบางTฟังก์ชั่นไบนารีบดคู่ขององค์ประกอบด้วยกันf :: T → T → Tและเช่นว่าคุณมีการเชื่อมโยงกฎหมายและกฎหมายประจำตัว:unit :: Tf(unit,x) = x = f(x,unit)

คุณสามารถสร้าง functor Uจากหมวดหมู่ของ monoids (ที่ลูกศรเป็น monoid homomorphisms นั่นคือพวกเขาให้แน่ใจว่าพวกเขาแมปunitไปunitที่ monoid อื่น ๆ และที่คุณสามารถเขียนก่อนหรือหลังการแมปไปยัง monoid อื่นโดยไม่เปลี่ยนความหมาย) เป็นหมวดหมู่ ของชุด (ที่ลูกศรเป็นเพียงลูกศรฟังก์ชั่น) ที่ 'ลืม' เกี่ยวกับการดำเนินการและunitและเพียงแค่ให้คุณตั้งค่าผู้ให้บริการ

จากนั้นคุณสามารถกำหนด functor Fจากหมวดหมู่ของชุดกลับไปที่หมวดหมู่ของ monoids ที่เหลือ adjoint กับ functor นี้ นั่นคือ functor functor ที่แมชุดaเพื่อหนังสือ[a]ที่และunit = []mappend = (++)

ดังนั้นเพื่อทบทวนตัวอย่างของเราจนถึงใน pseudo-Haskell:

U : Mon  Set -- is our forgetful functor
U (a,mappend,mempty) = a

F : Set  Mon -- is our free functor
F a = ([a],(++),[])

จากนั้นเพื่อแสดงให้Fเป็นอิสระเราต้องแสดงให้เห็นว่ามันเหลือ adjoint ให้Ufunctor ขี้ลืมนั่นคือที่เรากล่าวถึงข้างต้นเราต้องแสดงให้เห็นว่า

F a → b isomorphic ถึง a → U b

ตอนนี้จำได้ว่าเป้าหมายของการFอยู่ในหมวดหมู่Monของ monoids ที่ลูกศรมี homomorphisms หนังสือดังนั้นเราจึงจำเป็นที่จะแสดงให้เห็นว่า homomorphism หนังสือจากสามารถอธิบายได้อย่างแม่นยำโดยฟังก์ชั่นจาก[a] → ba → b

ใน Haskell เราเรียกด้านนี้ว่าชีวิตในSet(เอ้อHaskประเภทประเภท Haskell ที่เราแกล้งเป็นชุด) เพียงfoldMapซึ่งเมื่อผู้เชี่ยวชาญจากในรายการมีประเภทData.FoldableMonoid m => (a → m) → [a] → m

มีผลกระทบที่ตามมาจากการเป็นส่วนเสริม โดยเฉพาะอย่างยิ่งถ้าคุณลืมแล้วสร้างด้วยฟรีแล้วลืมอีกครั้งมันเหมือนคุณลืมครั้งเดียวและเราสามารถใช้สิ่งนี้เพื่อสร้างการเข้าร่วม monadic ตั้งแต่UFUF~ U(FUF)~ UFและเราสามารถส่งผ่านตัวตน monoid homomorphism จาก[a]ไป[a]ถึง isomorphism ที่กำหนด adjunction ของเราได้รับรายการ isomorphism จาก[a] → [a]เป็นหน้าที่ของประเภทa -> [a]และนี่เป็นเพียงกลับรายการ

คุณสามารถเขียนทั้งหมดนี้ได้โดยตรงโดยอธิบายรายการในคำศัพท์เหล่านี้ด้วย:

newtype List a = List (forall b. Monoid b => (a -> b) -> b)

Monad ฟรี

ดังนั้นสิ่งที่เป็นMonad ฟรี ?

เราทำแบบเดียวกับที่เราเคยทำมาก่อนเราเริ่มจาก functor U ที่หลงลืมจากหมวดหมู่ของ monads ที่ลูกศรนั้นเป็น homomorphisms monad ไปเป็นหมวดหมู่ของ endofunctors ที่ลูกศรมีการเปลี่ยนแปลงตามธรรมชาติและเรามองหา functor ที่เหลือ adjoint เพื่อที่

ดังนั้นสิ่งนี้เกี่ยวข้องกับแนวคิดของ monad ที่อิสระตามที่ใช้กันทั่วไปอย่างไร

รู้สิ่งที่เป็น monad ฟรีFree f, บอกคุณว่าให้ homomorphism monad จากFree f -> mเป็นสิ่งเดียวกัน (isomorphic ไป) การให้การเปลี่ยนแปลงธรรมชาติ (ก homomorphism functor) f -> mจาก จำไว้ว่าF a -> bต้องเป็น isomorphic เพื่อa -> U bให้ F เหลืออยู่ adjoint กับ U ที่นี่แมป monads กับ functors

F อย่างน้อย isomorphic กับFreeชนิดที่ฉันใช้ในfreeแพ็คเกจของฉันในการแฮ็ก

นอกจากนี้เรายังสามารถสร้างมันขึ้นมาในลักษณะที่คล้ายคลึงกับโค้ดด้านบนสำหรับรายการฟรีโดยการกำหนด

class Algebra f x where
  phi :: f x -> x

newtype Free f a = Free (forall x. Algebra f x => (a -> x) -> x)

Cofree Comonads

เราสามารถสร้างบางสิ่งที่คล้ายกันได้โดยดูที่คำ adjoint ที่ถูกต้องกับ functor ที่หลงลืมว่ามันมีอยู่ functor cofree เป็นเพียง / adjoint / ขวาไปลืม functor และสมมาตรรู้บางสิ่งบางอย่างเป็น comonad cofree เป็นเช่นเดียวกับที่ได้รู้ว่าให้ homomorphism comonad จากเป็นสิ่งเดียวกันกับการให้การเปลี่ยนแปลงจากธรรมชาติw -> Cofree fw -> f


12
@PauloScardine นี่คือสิ่งที่คุณไม่ต้องกังวล คำถามของฉันมาจากความสนใจที่จะเข้าใจโครงสร้างข้อมูลขั้นสูงบางอย่างและอาจจะได้เห็นสิ่งที่ล้ำสมัยในการพัฒนาของ Haskell ในตอนนี้ - มันไม่จำเป็นหรือเป็นตัวแทนของสิ่งที่เขียน Haskell จริงๆ (และหัวขึ้นมันจะดีขึ้นเมื่อคุณผ่านขั้นตอนการเรียนรู้ IO อีกครั้ง)
เดวิด

8
@PauloScardine คุณไม่จำเป็นต้องตอบคำถามข้างต้นเพื่อที่จะเขียนโปรแกรมอย่างมีประสิทธิภาพใน Haskell แม้จะมี monads ฟรี อันที่จริงฉันไม่แนะนำให้โจมตี monad ฟรีด้วยวิธีนี้กับคนที่ไม่มีพื้นฐานด้านทฤษฎีหมวดหมู่ มีหลายวิธีที่จะพูดคุยเกี่ยวกับมันจากมุมมองการดำเนินงานและวิธีการใช้งานโดยไม่ต้องดำน้ำในทฤษฎีหมวดหมู่ อย่างไรก็ตามเป็นไปไม่ได้ที่ฉันจะตอบคำถามเกี่ยวกับที่มาของพวกเขาโดยไม่ต้องดำดิ่งสู่ทฤษฎี กองกำลังอิสระเป็นเครื่องมือที่ทรงพลังในทฤษฎีหมวดหมู่ แต่คุณไม่จำเป็นต้องมีพื้นฐานนี้เพื่อใช้งาน
Edward KMETT

18
@PauloScardine: คุณไม่จำเป็นต้องมีแคลคูลัสในการใช้ Haskell อย่างมีประสิทธิภาพและเข้าใจสิ่งที่คุณทำอยู่ เป็นเรื่องแปลกที่จะบ่นว่า "ภาษานี้เป็นวิชาคณิตศาสตร์" เมื่อความฉลาดนั้นเป็นเพียงความดีเป็นพิเศษที่คุณสามารถใช้เพื่อความสนุกสนานและผลกำไร คุณไม่ได้รับสิ่งเหล่านี้ในภาษาที่จำเป็นที่สุด ทำไมคุณถึงบ่นเกี่ยวกับบริการพิเศษ? คุณสามารถเลือกที่จะไม่ให้เหตุผลทางคณิตศาสตร์และเข้าใกล้มันเหมือนที่คุณต้องการภาษาใหม่อื่น ๆ
ซาร่าห์

3
@ ซาร่าห์: ฉันยังไม่ได้เห็นเอกสารหรือการสนทนา IRC เกี่ยวกับฮาเซลที่ไม่หนักในทฤษฎีคอมพิวเตอร์และแลมบ์ดาแคลคูลัส
เปาโล Scardine

11
@PauloScardine สิ่งนี้ลอยอยู่เหนือ OT เล็กน้อย แต่ในการป้องกันของ Haskell: สิ่งที่คล้ายกันนี้ใช้กับภาษาโปรแกรมอื่น ๆ ทั้งหมดเท่านั้นที่ Haskell มีการรวบรวมที่ดีที่ผู้คนสามารถเพลิดเพลินกับการพูดคุยกับพวกเขา ทำไม / ทำไม X monad จึงน่าสนใจสำหรับหลาย ๆ คนการพูดคุยเกี่ยวกับมาตรฐาน IEEE ไม่ใช่ประเด็นสำคัญ ทั้งสองกรณีไม่สำคัญสำหรับคนส่วนใหญ่เพราะพวกเขาสามารถใช้ผลลัพธ์ได้
David

72

Free Monad (โครงสร้างข้อมูล) คือ Monad (class) เช่น List (โครงสร้างข้อมูล) to Monoid (class): เป็นการใช้งานเล็กน้อยที่คุณสามารถตัดสินใจได้ว่าจะรวมเนื้อหาอย่างไร


คุณอาจจะรู้ว่าสิ่งที่ Monad และที่แต่ละ Monad ความต้องการที่เฉพาะเจาะจง (Monad-ปฏิบัติตามกฎหมาย) การดำเนินการอย่างใดอย่างหนึ่งfmap+ join+ returnหรือ+bindreturn

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

ที่สามารถทำได้โดยใช้ Free Monad (โครงสร้างข้อมูล) ซึ่งห่อ Functor (ประเภท) ในลักษณะเพื่อที่joinจะค่อนข้างซ้อนของฟังก์ชั่นเหล่านั้นกว่าการลดลง

ของจริงreturnและjoinคุณต้องการใช้ตอนนี้สามารถให้เป็นพารามิเตอร์ในฟังก์ชั่นการลดfoldFree :

foldFree :: Functor f => (a -> b) -> (f b -> b) -> Free f a -> b
foldFree return join :: Monad m => Free m a -> m a

ที่จะอธิบายประเภทที่เราสามารถแทนที่Functor fด้วยMonad mและbด้วย(m a):

foldFree :: Monad m => (a -> (m a)) -> (m (m a) -> (m a)) -> Free m a -> (m a)

8
คำตอบนี้ทำให้ฉันรู้สึกว่าฉันเข้าใจสิ่งที่พวกเขาอาจมีประโยชน์
David

59

Monad ฟรีของ Haskell คือรายการของ functors เปรียบเทียบ:

data List a   = Nil    | Cons  a (List a  )

data Free f r = Pure r | Free (f (Free f r))

Pureคล้ายกับNilและFreeคล้ายคลึงกับConsจะคล้ายคลึงกับMonad ฟรีจะเก็บรายการของ functors แทนที่จะเป็นรายการของค่า ในทางเทคนิคคุณสามารถใช้ monads ฟรีโดยใช้ประเภทข้อมูลที่แตกต่างกัน แต่การใช้งานใด ๆ ที่ควรจะเป็น isomorphic กับข้างต้น

คุณใช้ monads ฟรีเมื่อใดก็ตามที่คุณต้องการแผนภูมิต้นไม้นามธรรม functor พื้นฐานของ monad ฟรีเป็นรูปทรงของแต่ละขั้นตอนของต้นไม้ไวยากรณ์

โพสต์ของฉันที่ใครบางคนเชื่อมโยงไว้แล้วให้ตัวอย่างหลาย ๆ วิธีในการสร้างต้นไม้ไวยากรณ์ที่เป็นนามธรรมพร้อมกับ monads ฟรี


6
ฉันรู้ว่าคุณเพิ่งวาดการเปรียบเทียบแทนที่จะสร้างคำจำกัดความ แต่ monad ที่ว่างก็ไม่เหมือนกับรายการของฟังก์ชั่นในทุกแง่มุม มันใกล้กับต้นไม้ของฟังก์ชั่น
Tom Ellis

6
ฉันยืนตามคำศัพท์ของฉัน ตัวอย่างเช่นการใช้แพ็คเกจดัชนีหลักของฉันคุณสามารถกำหนด "free monad comprehensions" ซึ่งทำงานเหมือนกับ list monad ยกเว้นว่าคุณผูกฟังก์ชันแทนที่จะเป็นค่า Monad ที่ว่างคือรายการของ functors ในแง่ที่ว่าถ้าคุณแปลแนวคิดของ Haskell ทั้งหมดในหมวดของ functors รายการนั้นจะกลายเป็น monads ที่ว่าง ต้นไม้แห่งหน้าที่ที่แท้จริงนั้นกลายเป็นสิ่งที่แตกต่างอย่างสิ้นเชิง
Gabriel Gonzalez

4
คุณคิดถูกว่า monad คือการจัดหมวดหมู่ในบางแง่มุมของแนวคิดของ monoid ดังนั้น monads อิสระจึงคล้ายกับ monoids อิสระเช่นรายการ ในระดับที่คุณถูกต้องอย่างแน่นอน อย่างไรก็ตามโครงสร้างของค่าของ monad ฟรีไม่ใช่รายการ มันเป็นต้นไม้ที่เป็นฉันรายละเอียดด้านล่าง
Tom Ellis

2
@TomEllis ในทางเทคนิคมันเป็นเพียงต้นไม้ถ้า functor ฐานของคุณเป็น functor ผลิตภัณฑ์ เมื่อคุณมีฟังก์ชั่นรวมเป็น functor พื้นฐานมันคล้ายกับเครื่องสแต็ค
Gabriel Gonzalez

21

ฉันคิดว่าตัวอย่างที่เป็นรูปธรรมจะช่วยได้ สมมติว่าเรามีนักแสดง

data F a = One a | Two a a | Two' a a | Three Int a a a

fmapด้วยสิ่งที่ชัดเจน จากนั้นFree F aเป็นชนิดของต้นไม้ที่มีใบมีชนิดaและมีต่อมน้ำติดแท็กด้วยOne, Two, และ Two' -nodes มีเด็กคนหนึ่ง- และ-nodes มีลูกสองคนและ-nodes มีสามและมีการติดแท็กยังกับThreeOneTwoTwo'ThreeInt

Free Fเป็น monad returnแผนที่กับต้นไม้ที่เป็นเพียงใบที่มีค่า x ดูใบไม้แต่ละใบแล้วแทนที่ด้วยต้นไม้ เมื่อใบมีค่าจะแทนที่ใบที่มีต้นไม้xt >>= fyf y

ไดอะแกรมทำให้ภาพชัดเจนขึ้น แต่ฉันไม่มีสิ่งอำนวยความสะดวกในการวาดภาพอย่างง่ายดาย!


14
สิ่งที่พวกคุณกำลังพูดคือ monad ที่เป็นอิสระนั้นมีรูปร่างของนักแสดง ดังนั้นหากนักแสดงเป็นเหมือนต้นไม้ (ผลิตภัณฑ์) monad ฟรีก็เหมือนต้นไม้ ถ้ามันเป็นแบบรายการ (จำนวนเงิน), monad ฟรีจะเป็นแบบรายการ; ถ้ามันเป็นฟังก์ชั่นเหมือนกัน monad ที่ว่างก็เหมือนฟังก์ชั่น ฯลฯ มันทำให้รู้สึกถึงฉัน เช่นเดียวกับใน monoid ฟรีคุณยังคงรักษาแอปพลิเคชันของ mappend ทุกตัวเพื่อสร้างองค์ประกอบใหม่อย่างสมบูรณ์ ใน monad ฟรีคุณถือว่าการใช้งานของนักแสดงทุกคนเป็นองค์ประกอบใหม่อย่างสมบูรณ์
Bartosz Milewski

4
แม้ว่า functor เป็น "sum functor" monad ฟรีที่เกิดยังคงเหมือนต้นไม้ คุณจบลงด้วยโหนดมากกว่าหนึ่งประเภทในทรีของคุณ: หนึ่งโหนดสำหรับแต่ละองค์ประกอบของผลรวมของคุณ หาก "sum functor" ของคุณคือ X -> 1 + X คุณจะได้รับรายการซึ่งเป็นต้นไม้ที่เสื่อมโทรม
Tom Ellis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.