Учитывая две монады, 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 и не нашел ничего полезного для этой темы.