Рассмотрим оператор композиции монадических функций <=<
.Это аналог .
, за исключением того, что он работает с монадическими функциями.Его можно определить просто в терминах >>=
, поэтому изучение одного из них даст нам представление о другом.
(<=<) :: (a -> m b) -> (b -> m c) -> a -> m c
(f <=< g) x = g x >>= f
(.) :: (a -> b) -> (b -> c) -> a -> c
(f . g) x = g x |> f
where z |> h = h z
В случае .
сначала выполняется «1008 *», изатем f
выполняется на выходе g
.В случае <=<
, g
и его эффекты сначала «выполняются», а затем f
и его эффекты выполняются.Было бы немного неправильно говорить, что одно происходит «раньше» другого, на самом деле, поскольку не все монады работают таким образом.
Возможно, точнее будет сказать, что f
может воспользоваться дополнительным контекстуальныминформация предоставлена g
.Но это не совсем правильно, поскольку g
может потенциально забрать контекстную информацию.Если вы хотите на 100% правильно описать монады, вам действительно нужно ходить по яичной скорлупе.
Но почти во всех нетривиальных случаях f <=< g
означает, что влияет (а также результат ) монадической функции g
будет впоследствии влиять на поведение монадической функции f
.
Чтобы ответить на вопросы о v >>= f = join (fmap f v)
Рассмотримf :: a -> m b
и v :: m a
.Что это значит для fmap f v
?Ну fmap :: (c -> d) -> m c -> m d
, а в данном случае c = a
и d = m b
, поэтому fmap f :: m a -> m (m b)
.Теперь, конечно, мы можем применить v :: m a
к этой функции, в результате чего m (m b)
.но что точно означает этот тип результата m (m b)
?
inner m
представляет контекст из f
. external m
представляет контекст, происходящий из v
(nb fmap
не должен нарушать этот исходный контекст).
И тогда вы join
that m (m b)
, разбиваяэти два контекста вместе в m a
.В этом суть определения Monad
: вы должны предоставить способ разбить контексты вместе.Вы можете проверить детали реализации различных Monad
экземпляров, чтобы попытаться понять, как они "разбивают" контексты вместе.Вывод здесь, однако, заключается в том, что «внутренний контекст» является ненаблюдаемым, пока вы не объедините его с «внешним контекстом».Если вы используете v >>= f
, тогда фактическое понятие функции f
не получает чистое значение a
и дает простой монадический результат m b
.Вместо этого мы понимаем, что f
действует в исходном контексте из v
.