#haskell
#хаскелл
Вопрос:
Когда я использую sequence
on Maybe
, кажется, все работает нормально:
sequence [Just 2, Just 3] == Just [2, 3]
sequence [Just 2, Just 3, Nothing] == Nothing
Тип результата соответствует sequence
типу: (Traversable t, Monad m) => t (m a) -> m (t a)
, m (t a)
становится Maybe [Int]
, и это тоже правильно Nothing
.
Однако, если я сделаю что-то подобное:
sequence [Right 2, Right 3] == Right [2, 3]
sequence [Right 2, Right 3, Left 4] == Left 4
Как Left 4
тип m (t a)
? Если Right [2, 3]
есть Either [Int]
, то Left 4
также следует использовать этот тип, но, очевидно (для меня), это не так. Чего мне не хватает?
Комментарии:
1.
Left
похожеNothing
на aMaybe
.2. Да, но он не нулевой, он принимает аргумент, и этот аргумент должен иметь тип, тот же тип
Right
, который принимает, насколько я понимаю.3.
m
здесьEither b
, нетEither
.
Ответ №1:
Давайте сначала проведем анализ типов. m
Нет Either
, m
есть m ~ Either b
. Действительно, поскольку m
принимает параметр одного типа.
Итак, если мы установим m ~ Either b
, то получим:
(Traversable t) => t (Either b a) -> Either b (t a)
и t ~ []
таким образом, мы получаем:
[Either b a] -> Either b [a]
Вы можете видеть Either b
, как более сложная версия Maybe
where Left e
используется для отображения ошибки (вычисления, которые завершились неудачно) с e
объектом error (это может быть, например, строка или какой-либо другой тип), и Right x
вычисления, которые завершились успешно с x
результатом. Таким образом, в этом случае sequence
будет проверяться, удалось ли выполнить список вычислений, и если это так, он вернет a Right [x1, x2, …, xn]
, и если одно из вычислений завершилось неудачно, оно вернет первый «объект ошибки».
Это основано на экземпляре Monad (Either b)
, действительно [src]:
-- | @since 4.4.0.0 instance Monad (Either e) where Left l >>= _ = Left l Right r >>= k = k r
Таким образом, для a Left l
он вернет a Left l
, тогда как для a Right
он будет применяться k
к результату r
.