В общем, то, что вы можете сделать это:
case getValue of
Right x -> Right $ negate x
e -> e
Что это делает должно быть ясны: это так же, как шаблон в качестве аргумента функции, но и против значения. Чтобы сделать то, что вам нужно, у вас есть случай по умолчанию, который ловит все, что не соответствует, а затем возвращает это.
В вашем конкретном случае, однако, вы можете сделать что-то немного приятнее:
negate `fmap` getValue
Или, с import Control.Applicative
, вы можете использовать <$>
как синоним fmap
(negate <$> getValue
). Функция fmap
имеет тип fmap :: Functor f => (a -> b) -> f a -> f b
. Для любого функтора , fmap
преобразует функцию по обычным значениям в функцию внутри функтора. Например, списки являются функторами, а для списков - fmap = map
. Здесь Either e
представляет собой функтор, который является либо исключением Left e
, либо значением Right a
; применение функции к Left
ничего не делает, но применение функции к Right
применяет ее в пределах Right
. Другими словами,
instance Functor (Either e) where
fmap _ (Left l) = Left l
fmap f (Right r) = Right $ f r
Таким образом, версия case
является прямым ответом на ваш вопрос, но ваш конкретный пример более хорошо аппроксимируется fmap
.
1: В первом приближении функторы являются «контейнерами». Если вам не нравятся различные типы классов, я рекомендовал the Typeclassopedia для получения полной справки; есть еще много учебников, и лучший способ почувствовать их - просто поиграть с ними. Тем не менее, fmap
для конкретных типов часто можно использовать (особенно, на мой взгляд, при написании <$>
).
И не забываете хороший 'либо левый (правый отрицать.) GetValue' от' Data.Either';) – ony
Благодарю. Выражение случая - это то, что я искал. Я не понимаю остальной части вашего ответа; Я вернусь к нему, когда узнаю больше. – titaniumdecoy
@ony: Я думаю, что вы должны написать свой комментарий в виде отдельного ответа, это действительно решение промежуточного уровня между 'case' и' fmap'! – yatima2975