В общем, что вы можете сделать, это:
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
. Для любого функтора 1 , 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: В первом приближении функторы являются «контейнерами». Если вам не нравятся различные классы типов, я рекомендую Typeclassopedia для полной справки; Есть много других учебных пособий, и лучший способ почувствовать их - просто поиграть с ними. Однако fmap
для определенных типов часто легко использовать (особенно, на мой взгляд, когда написано <$>
).