۲۴ - ۵دونَد؟
Monad
چطور؟ ترکیب ِ دو تایپِ دلخواه که نمونه ِ Monad
دارن هیچ اشکالی نداره. تو اون مثالی که با استفاده از Compose
تایپهای Maybe
و لیست (که هردوشون نمونه ِ Monad
دارن) رو ترکیب کردیم مشکلی نبود. با این حال، تایپِ حاصل از ترکیبشون، یه Monad
نمیده.
مشکل در کمبودِ اطلاعاته. هردو تایپهایی که Compose
باهاشون کار میکنه پلیمورفیک اند، پس وقتی میخواین برای Monad
بایند رو تعریف کنین، یعنی میخواین دوتا بایند ِ پلیمورفیک رو به یک بایند ترکیب کنین، که چنین چیزی ممکن نیست:
{-# LANGUAGE InstanceSigs #-}
-- .غیرممکن
instance (Monad f, Monad g)
=> Monad (Compose f g) where
return = pure
(>>=) :: Compose f g a
-> (a -> Compose f g b)
-> Compose f g b
(>>=) = ???
این دوتا، تایپهاییاند که میخوایم ترکیب کنیم، چون f
و g
هردوشون لزوماً موند هستن و نمونه ِ Monad
ِ خودشون رو دارن:
Monad f => f a -> (a -> f b) -> f a -> f b
Monad g => g a -> (a -> g b) -> g a -> g b
با توجه به اونها، چنین بایندی میخوایم بنویسیم:
(Monad f, Monad g)
=> f (g a) -> (a -> f (g b)) -> f (g b)
یا با فرمولی متفاوت:
(Monad f, Monad g)
=> f (g (f (g b))) -> f (g b)
و چنین چیزی غیرممکنه. هیچ راه خوبی برای join
کردنِ اون f
و g
ِ نهایی نیست. تمرینِ خیلی خوبیه که سعی کنین طوری بنویسین که کار کنه، چون به موانعِ آموزندهای میخورین. میتونین مقالهی مارک پی . جونز و لاک دوپونشیل با عنوانِ ترکیب موندها رو هم بخونین.
خبری از بوریتوی مجانی نیست
حالا که دیدیم گرفتنِ یه Monad
ِ دیگه از ترکیب ِ دو تایپِ دلخواه که نمونه ِ Monad
دارن غیرممکنه، چی کار میتونیم انجام بدیم تا برای ترکیبهای تایپها، نمونه ِ Monad
داشته باشیم؟ جواب، موند ترانسفورمرها اند. بعد از کمی استراحت (با تمرین) توضیح میدیم.