Я новичок в Haskell, и я работаю над некоторым кодом Haskell, который использует Either для обработки ошибок. Левый элемент Литера представляет ошибку, в то время как правый элемент представляет собой успешный результат. В коде часто используется аппликативный экземпляр Either, который, как представляется, предназначен для этого варианта использования.Преобразование списка Eithers в Либо со списком в нем
С данным объектом [Either e r]
, что является самым элегантным способом превратить его в объект типа Either e [r]
? Дело в том, что у нас может быть массив возвращаемых значений из некоторых функций, которые мы вызывали, и если какое-либо из этих возвращаемых значений является ошибкой, мы хотим получить эту ошибку и выбросить все остальное. Если у нескольких элементов массива есть ошибка, я предпочел бы получить самую левую ошибку, если это возможно.
Я смог решить эту проблему самостоятельно в коде ниже, написав две функции, одна из которых рекурсивна, но есть ли лучший способ?
type Error = [Char]
myFunc :: [Either Error a] -> Either Error [a]
myFunc = myFunc2 []
myFunc2 :: [a] -> [Either Error a] -> Either Error [a]
myFunc2 r ((Left error):rest) = Left error
myFunc2 r ((Right item):rest) = myFunc2 (r ++ [item]) rest
myFunc2 r [] = Right r
main :: IO()
main = do
-- This prints: Right [1, 2, 3]
putStrLn (show (myFunc [Right 1, Right 2, Right 3]))
-- This prints: Left "division by zero"
putStrLn (show (myFunc [Right 1, Left "division by zero", Right 3]))
В случае, если вы не в курсе, есть удобный сайт под названием [Hoogle] (https://www.haskell.org/hoogle/), где вы можете ввести тип -значение функции, которую вы хотите увидеть, и даст вам предложения о функциях с соответствующими/подобными сигнатурами. К сожалению, '[Либо lr] -> Либо l [r]', похоже, не дает никаких результатов :( – paul