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" также означает "correct").
Примеры
Тип 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"
Экземпляры
| Bifoldable Either Источник | С версии: base-4.10.0.0 |
Определено в Data.Bifoldable | |
| Bifoldable1 Either Источник | |
Определено в Data.Bifoldable1 | |
| Bifunctor Either Источник | С версии: base-4.8.0.0 |
| Bitraversable Either Источник | С версии: base-4.10.0.0 |
Определено в Data.Bitraversable Методыbitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> Either a b -> f (Either c d) Источник | |
| Eq2 Either Источник | С версии: base-4.9.0.0 |
| Ord2 Either Источник | С версии: base-4.9.0.0 |
Определено в Data.Functor.Classes | |
| Read2 Either Источник | С версии: base-4.9.0.0 |
| Eq a => Eq1 (Either a) Источник | С: base-4.9.0.0 |
| Ord a => Ord1 (Either a) Источник | С: base-4.9.0.0 |
Определено в Data.Functor.Classes | |
| Read a => Read1 (Either a) Источник | С: base-4.9.0.0 |
Определено в Data.Functor.Classes МетодыliftReadsPrec :: (Int -> ReadS a0) -> ReadS [a0] -> Int -> ReadS (Either a a0) Источник liftReadList :: (Int -> ReadS a0) -> ReadS [a0] -> ReadS [Either a a0] Источник liftReadPrec :: ReadPrec a0 -> ReadPrec [a0] -> ReadPrec (Either a a0) Источник liftReadListPrec :: ReadPrec a0 -> ReadPrec [a0] -> ReadPrec [Either a a0] Источник | |
| Show a => Show1 (Either a) Источник | С: base-4.9.0.0 |
| Applicative (Either e) Источник | С: base-3.0 |
Определено в GHC.Internal.Data.Either Методыpure :: a -> Either e a Исходный код (<*>) :: Either e (a -> b) -> Either e a -> Either e b Исходный код liftA2 :: (a -> b -> c) -> Either e a -> Either e b -> Either e c Исходный код (*>) :: Either e a -> Either e b -> Either e b Исходный код (<*) :: Either e a -> Either e b -> Either e a Исходный код | |
| Functor (Either a) Исходный код | С момента: base-3.0 |
Определено в GHC.Internal.Data.Either Методыfmap :: (a0 -> b) -> Either a a0 -> Either a b Исходный код (<$) :: a0 -> Either a b -> Either a a0 Исходный код | |
| Monad (Either e) Исходный код | С момента: base-4.4.0.0 |
Определено в GHC.Internal.Data.Either Методы(>>=) :: Either e a -> (a -> Either e b) -> Either e b Исходный код (>>) :: Either e a -> Either e b -> Either e b Исходный код return :: a -> Either e a Исходный код | |
| MonadFix (Either e) Исходный код | С момента: base-4.3.0.0 |
Определено в GHC.Internal.Control.Monad.Fix Методыmfix :: (a -> Either e a) -> Either e a Исходный код | |
| Foldable (Either a) Исходный код | С момента: base-4.7.0.0 |
Определено в GHC.Internal.Data.Foldable Методыfold :: Моноид m => Either a m -> m Исходный код foldMap :: Моноид m => (a0 -> m) -> Either a a0 -> m Исходный код foldMap' :: Моноид 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 -> Булево Исходный код length :: Either a a0 -> Целое Исходный код elem :: Eq a0 => a0 -> Either a a0 -> Булево Исходный код maximum :: Ord a0 => Either a a0 -> a0 Исходный код minimum :: Ord a0 => Either a a0 -> a0 Исходный код sum :: Num a0 => Either a a0 -> a0 Исходный код product :: Num a0 => Either a a0 -> a0 Исходный код | |
| Traversable (Either a) Исходный код | С момента: base-4.7.0.0 |
Определено в GHC.Internal.Data.Traversable Методыtraverse :: Применимый f => (a0 -> f b) -> Either a a0 -> f (Either a b) Исходный код sequenceA :: Применимый f => Either a (f a0) -> f (Either a a0) Исходный код mapM :: Моноид m => (a0 -> m b) -> Either a a0 -> m (Either a b) Исходный код sequence :: Моноид m => Either a (m a0) -> m (Either a a0) Исходный код | |
| Полугруппа (Either a b) Исходный код | С момента: base-4.9.0.0 |
Определено в GHC.Internal.Data.Either Методы(<>) :: Either a b -> Either a b -> Either a b Исходный код sconcat :: Непустой (Either a b) -> Either a b Исходный код stimes :: Целочисленный b0 => b0 -> Either a b -> Either a b Исходный код | |
| (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 Исходный код | |
| (Eq a, Eq b) => Eq (Either a b) Исходный код | С момента: base-2.1 |
Определено в GHC.Internal.Data.Either Методы(==) :: Either a b -> Either a b -> Bool Исходный код (/=) :: Either a b -> Either a b -> Bool Исходный код | |
| (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 Исходный код max :: Either a b -> Either a b -> Either a b Исходный код min :: Either a b -> Either a b -> Either a b Исходный код | |
| type Rep1 (Either a :: Type -> Type) Исходный код | С момента: base-4.6.0.0 |
Определено в GHC.Internal.Generics type Rep1 (Either a :: Тип -> Тип) = D1 ('MetaData "Either" "GHC.Internal.Data.Either" "ghc-internal" 'False) (C1 ('MetaCons "Left" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Символ) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)) :+: C1 ('MetaCons "Right" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Символ) '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 Символ) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)) :+: C1 ('MetaCons "Right" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Символ) '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. Затем мы применяем функцию «either» к функции 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 для написания очень простой функции отчётности об ошибках, которая ничего не делает в случае успеха и выводит «ERROR», если произошла какая-либо ошибка.
Этот пример демонстрирует, как 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 для написания очень простой функции отчётности, которая выводит только «SUCCESS», когда вычисление прошло успешно.
Этот пример демонстрирует, как 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.12.1/docs/libraries/base-4.21.0.0-8e62/Data-Either.html