Данные.Either
| Copyright | (c) The University of Glasgow 2001 |
|---|---|
| License | BSD-style (see the file libraries/base/LICENSE) |
| Maintainer | libraries@haskell.org |
| Stability | experimental |
| Portability | portable |
| Safe Haskell | Trustworthy |
| Language | Haskell2010 |
Описание
Тип Either и связанные операции.
Тип Either представляет значения с двумя возможностями: значение типа Either a b является либо Left a, либо Right b.
Тип Either иногда используется для представления значения, которое является либо правильным, либо ошибочным; по соглашению, конструктор Left используется для хранения значения ошибки, а конструктор Right используется для хранения правильного значения (мнемоника: "right" также означает "correct").
Примеры
Тип Either String Int — это тип значений, которые могут быть либо String, либо Int. Конструктор Left может использоваться только для Strings, а конструктор Right может использоваться только для Ints:
>>>let s = Left "foo" :: Either String Int>>>sLeft "foo">>>let n = Right 3 :: Either String Int>>>nRight 3>>>:type ss :: Either String Int>>>:type nn :: Either String Int
Функция fmap из нашего экземпляра Functor будет игнорировать значения Left, но будет применять предоставленную функцию к значениям, содержащимся в Right:
>>>let s = Left "foo" :: Either String Int>>>let n = Right 3 :: Either String Int>>>fmap (*2) sLeft "foo">>>fmap (*2) nRight 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' могут быть разобраны как Ints.
>>>:{let parseMultiple :: Either String Int parseMultiple = do x <- parseEither '1' y <- parseEither '2' return (x + y)>>>:}
>>>parseMultipleRight 3
Но следующее должно завершиться общей неудачей, так как первая операция, где мы пытаемся разобрать 'm' как Int, завершится неудачей:
>>>:{let parseMultiple :: Either String Int parseMultiple = do x <- parseEither 'm' y <- parseEither '2' return (x + y)>>>:}
>>>parseMultipleLeft "parse error"
Экземпляры
| Bifunctor Either | |
| Monad (Either e) | |
| Functor (Either a) | |
| MonadFix (Either e) | |
| Applicative (Either e) | |
| Foldable (Either a) | |
| Traversable (Either a) | |
| Generic1 (Either a) | |
| (Eq a, Eq b) => Eq (Either a b) | |
| (Data a, Data b) => Data (Either a b) | |
| (Ord a, Ord b) => Ord (Either a b) | |
| (Read a, Read b) => Read (Either a b) | |
| (Show a, Show b) => Show (Either a b) | |
| Generic (Either a b) | |
| type Rep1 (Either a) | |
| type Rep (Either a b) | |
| type (==) (Either k k1) a b |
either :: (a -> c) -> (b -> c) -> Either a b -> c Source
Анализ случаев для типа Either. Если значение является Left a, примените первую функцию к a; если это Right b, примените вторую функцию к b.
Примеры
Мы создаем два значения типа Either String Int, одно с использованием конструктора Left и другое с использованием конструктора Right. Затем мы применяем функцию "either" length (если у нас есть String) или функцию "times-two" (если у нас есть Int):
>>>let s = Left "foo" :: Either String Int>>>let n = Right 3 :: Either String Int>>>either length (*2) s3>>>either length (*2) n6
lefts :: [Either a b] -> [a] Source
Извлекает из списка 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] Source
Извлекает из списка Either все элементы Right. Все элементы Right извлекаются по порядку.
Примеры
Основное использование:
>>>let list = [ Left "foo", Right 3, Left "bar", Right 7, Left "baz" ]>>>rights list[3,7]
isLeft :: Either a b -> Bool Source
Возвращает 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
Since: 4.7.0.0
isRight :: Either a b -> Bool Source
Возвращает 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
Since: 4.7.0.0
partitionEithers :: [Either a b] -> ([a], [b]) Source
Разделяет список 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/7.10.3/docs/html/libraries/base-4.8.2.0/Data-Either.html