Давайте сделаем шаг назад на мгновение.У вас есть два типа функций, некоторые чисто с типами формы a -> b
, а некоторые монадические типа a -> m b
.
Чтобы избежать путаницы, давайте также придерживаться композиции справа налево.Если вы предпочитаете читать слева направо, просто измените порядок функций и замените (<=<)
на (>=>)
, а (.)
на (>>>)
из Control.Arrow
.
четыре варианта того, как их можно составить.
Чистый, а затем чистый. Используйте обычную композицию функций (.)
.
g :: a -> b
f :: b -> c
f . g :: a -> c
Чистый затеммонадическая .Также используйте (.)
.
g :: a -> b
f :: b -> m c
f . g :: a -> m c
Monadic, а затем monadic .Используйте композицию Клейсли (<=<)
.
g :: a -> m b
f :: b -> m c
f <=< g :: a -> m c
Монадическую, затем чистую .Используйте fmap
для чистой функции и (.)
для композиции.
g :: a -> m b
f :: b -> c
fmap f . g :: a -> m c
Игнорируя специфику задействованных типов, ваши функции:
flagWeekEnds :: a -> b
flagHolidays :: b -> c
flagScheduled :: c -> m d
flagASAP :: d -> m e
toWorkDays :: e -> f
Пойдем сверху.flagWeekEnds
и flagHolidays
оба чисты.Случай 1.
flagHolidays . flagWeekEnds
:: a -> c
Это чисто.Далее идет flagScheduled
, что является монадическим.Случай 2.
flagScheduled . flagHolidays . flagWeekEnds
:: a -> m d
Далее следует flagASAP
, теперь у нас есть две монадические функции.Случай 3.
flagASAP <=< flagScheduled . flagHolidays . flagWeekEnds
:: a -> m e
И, наконец, у нас есть чистая функция toWorkDays
.Случай 4.
fmap toWorkDays . flagASAP <=< flagScheduled . flagHolidays . flagWeekEnds
:: a -> m f
И все готово.