Относительно монад:
Да, Either a
- это монада.Итак, чтобы упростить задачу, вы в основном просите об этом:
main = print $ magicMonadUnwrap v
v :: Either String Int
v = Right 3
magicMonadUnwrap :: (Monad m) => m a -> a
magicMonadUnwrap = undefined
Как вы определяете magicMonadUnwrap
?Ну, вы видите, это отличается для каждой монады.Каждому нужен свой собственный распаковщик.У многих из них есть слово «бежать», например, runST
, runCont
или runEval
.Однако для некоторых монад, возможно, небезопасно их разворачивать (отсюда и необходимость в развертываниях по-разному).
Одна реализация для списков будет head
.Но что, если список пуст?Развертывание для Maybe
- это fromJust
, но что, если это Nothing
?
Точно так же развертывание для монады Either
будет выглядеть примерно так:
fromRight :: Either a b -> b
fromRight (Right x) = x
Ноэтот распаковщик небезопасен: что, если вместо этого у вас было значение Left
?(Слева обычно представляет состояние ошибки, в вашем случае, ошибка разбора).Таким образом, лучший способ воздействовать на значение Either
- это использовать функцию either
или использовать оператор case, соответствующий Right
и Left
, как иллюстрировал Даниэль Вагнер.
tl; dr : нет magicMonadUnwrap
.Если вы находитесь внутри той же монады, вы можете использовать <-
, но чтобы действительно извлечь значение из монады ... ну ... как вы это сделаете, зависит от того, с какой монадой вы имеете дело.