۲۴ - ۵دونَد؟
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 داشته باشیم؟ جواب، موند ترانسفورمرها اند. بعد از کمی استراحت (با تمرین) توضیح میدیم.