Сопоставление либо слева
Где-то в моем приложении я получаю Either ParserError MyParseResult
от Parsec. В результате этого результата выполняется другой анализ, использующий другие библиотеки. Во время этой второй фазы синтаксического анализа также может возникнуть некоторая ошибка, которую я хотел бы передать как Left String
, но для этого мне также нужно преобразовать результат из Parsec в String
. Чтобы достичь этого, мне нужна функция, которая позволит мне отобразить через Left
с помощью функции show
.
Функция отображения, о которой я думаю, выглядит примерно так:
mapLeft :: (a -> b) -> Either a c -> Either b c
mapLeft f (Left x) = Left $ f x
mapLeft _ x = x
Но я был очень удивлен, не найдя ничего подходящего для hackage db. Итак, теперь у меня возникают сомнения в том, что я использую правильный подход к моей проблеме.
Почему в стандартной библиотеке нет такой функции? Что не так с моим подходом?
Ответы
Ответ 1
У нас есть такая функция в стандартных библиотеках,
Control.Arrow.left :: a b c -> a (Either b d) (Either c d)
- обобщение на произвольные стрелки. Замените (->)
на a
и примените его infix, чтобы получить специализацию
left :: (b -> c) -> Either b d -> Either c d
Нет ничего плохого в вашем подходе в принципе, это разумный способ справиться с ситуацией.
Ответ 2
Другой вариант - использовать экземпляр Bifunctor
для Either
. Тогда у вас есть
first :: (a -> b) -> Either a c -> Either b c
(Также Bifunctor
может быть использован для перемещения по первой части (a,b)
.)
Ответ 3
Это можно легко сделать с помощью lens:
import Control.Lens
over _Left (+1) $ Left 10 => Left 11
over _Left (+1) $ Right 10 => Right 10
over _Right (+1) $ Right 10 => Right 11
Ответ 4
Другой простой вариант - mapLeft
в Data.Either.Combinators
:
mapLeft :: (a -> c) -> Either a b -> Either c b