Предположим, у меня есть две функции
f :: Monad m => a -> m a
g :: a -> a
, которые я хочу последовательно применить к некоторому элементу, например так:
(return x) >>= f >>= g
Это не работает, потому что g чисто, поэтому я Сначала нужно «искусственно» включить монаду c. Одна возможность -
(return x) >>= f >>= (return . g)
, которая не очень интуитивна для меня. Другая возможность состоит в том, чтобы использовать монаду Аппликативно:
(return g) <*> ((return x) >>= f)
Но это не очень интуитивно понятно из-за разного порядка функций и аргументов:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Что такое канонический способ иметь дело с этим? Если (>>==) = (flip ((<*>) . pure))
, можно написать ((pure x) >>= f) >>== g
, что было бы хорошо, за исключением приоритета оператора. Конечно, чистые функции в коде monadi c являются обычным делом, поэтому наверняка есть стандартный способ с ними справиться?
Редактировать: Первоначально я не говорил этого, но я думал о ситуации, когда я имел несколько функций, некоторые чистые, некоторые монади c, и я хотел применить их в некотором случайном порядке.