Я пытаюсь сделать то, что должно быть ослепительно очевидным в Haskell, которое идет от Just [1]
и Just [2]
до Just [1, 2]
. Однако я не могу найти что-либо в Интернете, поскольку я продолжаю находить связанные, но бесполезные страницы. Итак, как вы это достигаете?Слияния/добавления Justs в Haskell
ответ
Вы можете использовать liftA2 (++)
:
liftA2 (++) :: Maybe [a] -> Maybe [a] -> Maybe [a]
liftA2
просто поднимает бинарную функцию в Applicative
. Applicative
s были предназначены для подъема функций произвольных аргументов в контексте, поэтому они идеально подходят для этого. В этом случае используется Applicative
: Maybe
. Чтобы увидеть, как это работает, мы можем посмотреть на определение:
liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = f <$> a <*> b
(<$>)
просто поднимает любую функцию на чистых значений одной операционной внутри f
: (a -> b) -> f a -> f b
. (Это просто псевдоним для fmap
, если вы знакомы с Functor
с.) Для Maybe
:
_ <$> Nothing = Nothing
f <$> Just x = Just (f x)
(<*>)
немного сложнее: он применяет функцию внутри f
к значению внутри f
: f (a -> b) -> f a -> f b
. Для Maybe
:
Just f <*> Just x = Just (f x)
_ <*> _ = Nothing
(На самом деле, f <$> x
это то же самое, как pure f <*> x
, который Just f <*> x
для Maybe
.)
Таким образом, мы можем расширить определение liftA2 (++)
:
liftA2 (++) a b = (++) <$> a <*> b
-- expand (<$>)
liftA2 (++) (Just xs) b = Just (xs ++) <*> b
liftA2 (++) _ _ = Nothing
-- expand (<*>)
liftA2 (++) (Just xs) (Just ys) = Just (xs ++ ys)
liftA2 (++) _ _ = Nothing
Действительно, мы можем использовать эти операторы для подъема функции любой количество аргументов в любые Applicative
, j ust, следуя схеме liftA2
. Это называется аппликативный стиль и очень распространен в идиоматическом коде Haskell. В этом случае может быть даже более идиоматично использовать его непосредственно, написав (++) <$> a <*> b
, если a
и b
уже являются переменными. (С другой стороны, если вы частично применить его - скажем, передать его функции высшего порядка - то liftA2 (++)
предпочтительнее.)
Каждый Monad
является Applicative
, так что если вы когда-нибудь найти себя, пытаясь «поднять» функцию в контекст, Applicative
- это, вероятно, то, что вы ищете.
в то время как @ ehird Ответим велик, я бы использовал noobish решение в виде:
mergeJust a b = do
a' <- a
b' <- b
return (a' ++ b')
+1 даже noobs, оснащенный простыми инструментами, может решить эту проблему. Вы также можете написать то же, что и монадское понимание: '[a '++ b' | a '<- a, b' <- b] ' –
Чтобы расширить решение списка Just
с, вы могли бы использовать
fmap join $ sequence [Just[1],Just[2],Just[3]]
-- Just [1,2,3]
Поскольку он не упоминался в других решениях, я скажу это здесь. Самый простой способ выполнить вашу задачу, на мой взгляд, - использовать <>
(или mappend
) от Data.Monoid
.
import Data.Monoid
Just [1,2] <> Just [7,8] == Just [1,2,7,8]
Однако следует отметить, что это решение, в отличии от аппликативного раствора ehird, в не будет короткое замыкание на Nothing
значений.
Just [1,2] <> Nothing ---> Just [1,2]
--However
(++) <$> Just [1,2] <*> Nothing ---> Nothing
Иногда это будет правильное поведение, иногда нет. –
- 1. Написать интерпретатор Haskell в Haskell
- 2. Haskell- Как вернуться в список в haskell?
- 3. Возможности для генерации типов Haskell в Haskell («Haskell второго порядка»)?
- 4. Haskell: Работа с ошибками/исключениями в Haskell
- 5. Haskell - Неполное сопоставление с образцом в Haskell
- 6. Haskell: Template Haskell и область
- 7. Как разобрать источник Haskell в AST в Haskell?
- 8. Haskell Рекурсия: функция чередования в программировании в Haskell ch.11
- 9. "fold" в Haskell?
- 10. Оператор & в haskell?
- 11. модули Импорт в Haskell
- 12. Явная рекурсия в Haskell
- 13. Сглаживание списка в Haskell
- 14. Равенство функций в Haskell
- 15. Арифметика Char в Haskell
- 16. Рекуррентные отношения в haskell
- 17. вложенным, если в Haskell
- 18. Сравнение типов в Haskell
- 19. Модульный инверсный в Haskell
- 20. замена союза в haskell
- 21. предиката Логика в Haskell
- 22. Невозможно заменить в Haskell
- 23. (эмулируется) Макросы в Haskell?
- 24. Cubesumming в Haskell
- 25. Безопасное приложение в Haskell
- 26. Устранение неполадок в Haskell
- 27. Понимание списков в Haskell
- 28. Функция рекурсии в Haskell
- 29. Лун алгоритм в Haskell
- 30. Неоднозначность типов в Haskell
Awesome :) Спасибо, ты спас меня, вырвав мои волосы. Не думайте, что вы знаете эквивалент для '[2]' и 'Just [3]' -> 'Just [2, 3]' вы? :) –
@DeanBarnes: '(2 :) <$> Just [3]' –
Фантастический ответ, спасибо @ehird! Это в основном моя ссылка с этого момента :) –