Учитывая две монады, Monad m и Monad n, я хотел бы преобразовать m (n a) в n (m a). Но, как представляется, не существует общего способа, поскольку и (>>=), и return имеет дело только с одним типом монады, и хотя (>>=) позволяет извлекать содержимое из монады, вы должны упаковать их обратно в один и тот же тип монады, чтобы он мог значение результата.
Однако, если мы установим m на фиксированный тип, задание станет легким. Возьмите Maybe в качестве примера:
reorder :: (Monad n) => Maybe (n a) -> n (Maybe a)
reorder Nothing = return Nothing
reorder (Just x) = do
x' <- x
return $ Just x'
Или список:
reorder :: (Monad n) => [n a] -> n [a]
reorder [] = return []
reorder (x:xs) = do
x' <- x
xs' <- reorder xs
return (x':xs')
Не трудно увидеть, у нас есть образец здесь. Чтобы быть более очевидным, напишите его с помощью Applicative, и это не более чем применение конструктора данных к каждому элементу:
reorder (Just x) = Just <$> x
reorder (x:xs) = (:) <$> x <*> (reorder xs)
Мой вопрос: существует ли уже класс haskell для описания таких операций, или я должен сам изобретать колесо?
У меня был короткий поиск в документации GHC и не нашел ничего полезного для этой темы.