Поднимите значение ошибки до монадного преобразователя ErrorT

Я думаю, что мне не хватает базового понимания преобразователей монад, потому что я обнаружил, что пишу этот код:

import Control.Monad.Identity
import Control.Monad.Error

liftError :: Either String Int -> ErrorT String Identity Int
liftError x = do case x of
                    Right val -> return val
                    Left err -> throwError err

gateway :: Bool -> ErrorT String Identity Int
gateway = liftError . inner

inner :: Bool -> Either String Int
inner True = return 5
inner False = throwError "test"

Хотя это работает, я думаю, что это можно было бы сделать более элегантно. В частности, я ищу замену liftError, которую, я думаю, мне не нужно определять для себя.

Какой самый простой способ заставить gateway и inner работать вместе, не меняя их тип?


person Niklas B.    schedule 04.04.2012    source источник


Ответы (1)


Если вы просто немного поменяете типы, вам вообще не придется делать никаких подъемов.

{-# LANGUAGE FlexibleContexts #-}

gateway :: Bool -> ErrorT String Identity Int
gateway = inner

inner :: MonadError String m => Bool -> m Int
inner True = return 5
inner False = throwError "test"

MonadError имеет экземпляры как для ErrorT, так и для Either, поэтому вы можете использовать inner как оба.

person hammar    schedule 04.04.2012
comment
Итак, чтобы быть более конкретным, мне нужно написать функцию подъема вручную, если я хочу оставить типы такими, какие они есть? Это просто для моего понимания. Кстати, к сожалению, сегодня я больше не могу голосовать :/ Вы получите голос завтра :) - person Niklas B.; 04.04.2012
comment
Не изменяя типы, вы можете использовать ErrorT . return вместо вашей функции liftError. Вы также можете использовать более общую версию для внутреннего использования и предоставлять только копию inner с ограниченным типом. - person hammar; 04.04.2012
comment
Этот ErrorT . return был именно тем, что я искал. Как я уже упоминал, это не имеет ничего общего с каким-либо реальным кодом, я просто хочу понять концепцию монадных трансформеров :) - person Niklas B.; 04.04.2012