Я написал программу для извлечения Maybeпары:
deMaybe:: (a, Maybe b) -> Maybe (a, b)
deMaybe (_, Nothing) = Nothing
deMaybe (x,Just y) = Just (x, y)
Я знаю, что Maybeэто монада и (,) aфунктор (среди других классов типов). Мне интересно, есть ли функция более высокого уровня, которую мне не хватает, например:
commute:: (Functor f, Monad m) => f (m a) -> m (f a)
Мой вопрос: могу ли я написать deMaybeс более общей сигнатурой типа, такой как гипотетическая commute, признавая, что я пытаюсь коммутировать один функтор с другим? Можно ли это сделать с помощью таких функций, как fmap, >>=, pure, и т. д.?
Решение проблемы
Вы можете работать с sequence:: (Traversable t, Monad m) => t (m a) -> m (t a), но для этого требуется файл Traversable. Таким образом, для t ~ (b, )и m ~ Maybeэто работает как:
Prelude> sequence (2, Just 3)
Just (2,3)
Prelude> sequence (2, Nothing)
Nothing
A Traversable— это класс типов для структур данных, которые можно преобразовать в элемент той же формы. Нам нужно это, чтобы построить таким образом 2-кортеж (или список, или что-то подобное).
или мы можем использовать sequenceA:: (Traversable t, Applicative f) => t (f a) -> f (t a), как говорит @chepner, что является более общим, поскольку все Monads также являются Applicatives:
Prelude> sequenceA (2, Just 3)
Just (2,3)
Prelude> sequenceA (2, Nothing)
Nothing
Комментариев нет:
Отправить комментарий