Data.Either
| Авторские права | (c) Университет Глазго, 2001 |
|---|---|
| Лицензия | В стиле BSD (см. файл libraries/base/LICENSE) |
| Сопровождающий | libraries@haskell.org |
| Стабильность | стабильный |
| Переносимость | переносимый |
| Безопасный Haskell | Безопасный |
| Язык | Haskell2010 |
Описание
Тип Either и связанные с ним операции.
Тип Either представляет значения с двумя возможностями: значение типа Either a b является либо Left a, либо Right b.
Тип Either иногда используется для представления значения, которое либо корректно, либо является ошибкой; по соглашению конструктор Left используется для хранения значения ошибки, а конструктор Right — для хранения корректного значения (подсказка для запоминания: слово «right» также означает «правильный»).
Примеры
Тип Either String Int — это тип значений, которые могут быть либо String, либо Int. Конструктор Left можно использовать только для String, а конструктор Right — только для Int:
>>> let s = Left "foo" :: Either String Int >>> s Left "foo" >>> let n = Right 3 :: Either String Int >>> n Right 3 >>> :type s s :: Either String Int >>> :type n n :: Either String Int
fmap из нашего экземпляра Functor будет игнорировать значения Left, но применит переданную функцию к значениям, содержащимся в Right:
>>> let s = Left "foo" :: Either String Int >>> let n = Right 3 :: Either String Int >>> fmap (*2) s Left "foo" >>> fmap (*2) n Right 6
Экземпляр Monad для Either позволяет объединить в цепочку несколько действий, каждое из которых может завершиться неудачей; вся цепочка завершится неудачей, если не удалось выполнить хотя бы один шаг. Сначала напишем функцию, которая может либо разобрать Int из Char, либо завершиться неудачей.
>>> import Data.Char ( digitToInt, isDigit )
>>> :{
let parseEither :: Char -> Either String Int
parseEither c
| isDigit c = Right (digitToInt c)
| otherwise = Left "parse error"
>>> :}
Следующий пример должен работать, поскольку и '1', и '2' можно разобрать как Int:
>>> :{
let parseMultiple :: Either String Int
parseMultiple = do
x <- parseEither '1'
y <- parseEither '2'
return (x + y)
>>> :}
>>> parseMultiple Right 3
Однако следующий пример должен завершиться неудачей, поскольку первая операция, в которой мы пытаемся разобрать 'm' как Int, завершится неудачей:
>>> :{
let parseMultiple :: Either String Int
parseMultiple = do
x <- parseEither 'm'
y <- parseEither '2'
return (x + y)
>>> :}
>>> parseMultiple Left "parse error"
Экземпляры
Определено в GHC.Internal.Data.Either | |
| Functor (Either a) Источник | Начиная с: base-3.0 |
| Monad (Either e) Источник | Начиная с: base-4.4.0.0 |
| MonadFix (Either e) Источник | Начиная с: base-4.3.0.0 |
Определено в GHC.Internal.Control.Monad.Fix | |
| Foldable (Either a) Источник | Начиная с: base-4.7.0.0 |
Определено в GHC.Internal.Data.Foldable Методыfold :: Monoid m => Either a m -> m Источник foldMap :: Monoid m => (a0 -> m) -> Either a a0 -> m Источник foldMap' :: Monoid m => (a0 -> m) -> Either a a0 -> m Источник foldr :: (a0 -> b -> b) -> b -> Either a a0 -> b Источник foldr' :: (a0 -> b -> b) -> b -> Either a a0 -> b Источник foldl :: (b -> a0 -> b) -> b -> Either a a0 -> b Источник foldl' :: (b -> a0 -> b) -> b -> Either a a0 -> b Источник foldr1 :: (a0 -> a0 -> a0) -> Either a a0 -> a0 Источник foldl1 :: (a0 -> a0 -> a0) -> Either a a0 -> a0 Источник toList :: Either a a0 -> [a0] Источник null :: Either a a0 -> Bool Источник length :: Either a a0 -> Int Источник elem :: Eq a0 => a0 -> Either a a0 -> Bool Источник maximum :: Ord a0 => Either a a0 -> a0 Источник minimum :: Ord a0 => Either a a0 -> a0 Источник | |
| Traversable (Either a) Источник | Начиная с: base-4.7.0.0 |
Определено в GHC.Internal.Data.Traversable Методыtraverse :: Applicative f => (a0 -> f b) -> Either a a0 -> f (Either a b) Источник sequenceA :: Applicative f => Either a (f a0) -> f (Either a a0) Источник mapM :: Monad m => (a0 -> m b) -> Either a a0 -> m (Either a b) Источник sequence :: Monad m => Either a (m a0) -> m (Either a a0) Источник | |
| Semigroup (Either a b) Источник | Начиная с: base-4.9.0.0 |
| (Eq a, Eq b) => Eq (Either a b) Источник | Начиная с: base-2.1 |
| (Ord a, Ord b) => Ord (Either a b) Источник | Начиная с: base-2.1 |
Определено в GHC.Internal.Data.Either Методыcompare :: Either a b -> Either a b -> Ordering Источник (<) :: Either a b -> Either a b -> Bool Источник (<=) :: Either a b -> Either a b -> Bool Источник (>) :: Either a b -> Either a b -> Bool Источник (>=) :: Either a b -> Either a b -> Bool Источник | |
| (Data a, Data b) => Data (Either a b) Источник | Начиная с: base-4.0.0.0 |
Определено в GHC.Internal.Data.Data Методыgfoldl :: (forall d b0. Data d => c (d -> b0) -> d -> c b0) -> (forall g. g -> c g) -> Either a b -> c (Either a b) Источник gunfold :: (forall b0 r. Data b0 => c (b0 -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Either a b) Источник toConstr :: Either a b -> Constr Источник dataTypeOf :: Either a b -> DataType Источник dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Either a b)) Источник dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Either a b)) Источник gmapT :: (forall b0. Data b0 => b0 -> b0) -> Either a b -> Either a b Источник gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Either a b -> r Источник gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Either a b -> r Источник gmapQ :: (forall d. Data d => d -> u) -> Either a b -> [u] Источник gmapQi :: Int -> (forall d. Data d => d -> u) -> Either a b -> u Источник gmapM :: Monad m => (forall d. Data d => d -> m d) -> Either a b -> m (Either a b) Источник gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Either a b -> m (Either a b) Источник gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Either a b -> m (Either a b) Источник | |
| Generic (Either a b) Источник | |
Определён в GHC.Internal.Generics Связанные типы
Методыfrom :: Either a b -> Rep (Either a b) x Исходный код to :: Rep (Either a b) x -> Either a b Исходный код | |||||
| (Read a, Read b) => Read (Either a b) Исходный код | Начиная с: base-3.0 |
||||
Определён в GHC.Internal.Data.Either МетодыreadsPrec :: Int -> ReadS (Either a b) Исходный код readList :: ReadS [Either a b] Исходный код readPrec :: ReadPrec (Either a b) Исходный код readListPrec :: ReadPrec [Either a b] Исходный код | |||||
| (Show a, Show b) => Show (Either a b) Исходный код | Начиная с: base-3.0 |
||||
Определён в GHC.Internal.Data.Either МетодыshowsPrec :: Int -> Either a b -> ShowS Исходный код show :: Either a b -> String Исходный код showList :: [Either a b] -> ShowS Исходный код | |||||
| type Rep1 (Either a :: Type -> Type) Исходный код | Начиная с: base-4.6.0.0 |
||||
Определён в GHC.Internal.Generics type Rep1 (Either a :: Type -> Type) = D1 ('MetaData "Either" "GHC.Internal.Data.Either" "ghc-internal" 'False) (C1 ('MetaCons "Left" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)) :+: C1 ('MetaCons "Right" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1)) | |||||
| type Rep (Either a b) Исходный код | Начиная с: base-4.6.0.0 |
||||
Определён в GHC.Internal.Generics type Rep (Either a b) = D1 ('MetaData "Either" "GHC.Internal.Data.Either" "ghc-internal" 'False) (C1 ('MetaCons "Left" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)) :+: C1 ('MetaCons "Right" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 b))) | |||||
either :: (a -> c) -> (b -> c) -> Either a b -> c Исходный код
Анализ случая для типа Either. Если значение — Left a, применяет первую функцию к a; если это Right b, применяет вторую функцию к b.
Примеры
Создадим два значения типа Either String Int: одно с помощью конструктора Left, а другое — с помощью конструктора Right. Затем применим «либо» функцию length (если у нас есть String), либо функцию «умножить на два» (если у нас есть Int):
>>> let s = Left "foo" :: Either String Int >>> let n = Right 3 :: Either String Int >>> either length (*2) s 3 >>> either length (*2) n 6
lefts :: [Either a b] -> [a] Исходный код
Извлекает из списка Either все элементы Left. Все элементы Left извлекаются в исходном порядке.
Примеры
Пример использования:
>>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] >>> lefts list ["foo","bar","baz"]
rights :: [Either a b] -> [b] Исходный код
Извлекает из списка Either все элементы Right. Все элементы Right извлекаются в исходном порядке.
Примеры
Пример использования:
>>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] >>> rights list [3,7]
isLeft :: Either a b -> Bool Исходный код
Возвращает True, если переданное значение является значением Left, и False в противном случае.
Примеры
Пример использования:
>>> isLeft (Left "foo") True >>> isLeft (Right 3) False
Предположим, что значение Left обозначает ошибку. Тогда с помощью isLeft можно написать очень простую функцию обработки ошибок, которая ничего не делает в случае успеха и выводит «ОШИБКА», если произошла ошибка.
В этом примере показано, как можно использовать isLeft, чтобы избежать сопоставления с образцом, когда нас не интересует значение, содержащееся в конструкторе:
>>> import Control.Monad ( when ) >>> let report e = when (isLeft e) $ putStrLn "ERROR" >>> report (Right 1) >>> report (Left "parse error") ERROR
Начиная с: base-4.7.0.0
isRight :: Either a b -> Bool Исходный код
Возвращает True, если переданное значение является значением Right, и False в противном случае.
Примеры
Пример использования:
>>> isRight (Left "foo") False >>> isRight (Right 3) True
Предположим, что значение Left обозначает ошибку. Тогда с помощью isRight можно написать очень простую функцию отчёта, которая выводит «УСПЕХ» только в случае успешного выполнения вычисления.
В этом примере показано, как можно использовать isRight, чтобы избежать сопоставления с образцом, когда нас не интересует значение, содержащееся в конструкторе:
>>> import Control.Monad ( when ) >>> let report e = when (isRight e) $ putStrLn "SUCCESS" >>> report (Left "parse error") >>> report (Right 1) SUCCESS
Начиная с: base-4.7.0.0
fromLeft :: a -> Either a b -> a Исходный код
Возвращает содержимое значения Left или значение по умолчанию в противном случае.
Примеры
Пример использования:
>>> fromLeft 1 (Left 3) 3 >>> fromLeft 1 (Right "foo") 1
Начиная с: base-4.10.0.0
fromRight :: b -> Either a b -> b Исходный код
Возвращает содержимое значения Right или значение по умолчанию в противном случае.
Примеры
Пример использования:
>>> fromRight 1 (Right 3) 3 >>> fromRight 1 (Left "foo") 1
Начиная с: base-4.10.0.0
partitionEithers :: [Either a b] -> ([a], [b]) Исходный код
Разбивает список Either на два списка. Все элементы Left извлекаются по порядку в первый компонент результата. Аналогично, элементы Right извлекаются во второй компонент результата.
Примеры
Пример использования:
>>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] >>> partitionEithers list (["foo","bar","baz"],[3,7])
Пара, возвращённая partitionEithers x, должна совпадать с парой (lefts x, rights x):
>>> let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ] >>> partitionEithers list == (lefts list, rights list) True
© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/9.14.1/docs/libraries/base-4.22.0.0-66f8/Data-Either.html