Spec-Zone.ru › Haskell 7

Данные.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 и связанные операции.

data Either a b Source

Тип 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
>>> 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' могут быть разобраны как Ints.

>>> :{
    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"

Конструкторы

Left a
Right b

Экземпляры

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) s
3
>>> either length (*2) n
6

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API