Use ReaderT Maybe or MaybeT Reader?

I want to write a haskell program read config and do something. The configuration Data.Map

will be entered into the Reader. And when we cannot find the configuration item, the reading should be interrupted. Just stopped, no error messages required. So I just want the Maybe monad (not Either monad).

The problem is how should I add the two monads, ReaderT Maybe

or MaybeT Reader

?

+3


source to share


1 answer


Finally I got it. Both are fine.

Suppose each config item value is just Int.

ReaderT ConfigMap Maybe Int

will have a value similar to:

ReaderT (\r -> Just 123)

      

or

ReaderT (\r -> Nothing)

      

MaybeT (Reader ConfigMap) Int

will have a value similar to:

MaybeT (Reader (\r -> Just 123))

      



or

MaybeT (Reader (\r -> Nothing))

      

With either, we can do some reading first and then decide whether we should continue according to whether read a is reading Nothing

. The values ​​have different external forms but have the same functionality.

My little demo is here:

import qualified Data.Map as M
import Control.Monad
import Control.Monad.Reader
import Control.Monad.Trans
import Control.Monad.Trans.Maybe

type Config = M.Map String Int

getConfig :: String -> MaybeT (Reader Config) Int
getConfig key = MaybeT $ do
  m <- ask
  return $ M.lookup key m

readAll :: Config -> Maybe (Int, Int)
readAll m =
  let r = runMaybeT $ do
      a <- getConfig "a"
      b <- getConfig "b"
      return (a, b)
  in runReader r m

main :: IO ()
main = do
  putStrLn $ show (readAll $ M.fromList [("x", 3), ("b", 4)])

      

My second demo:

import qualified Data.Map as M
import Control.Monad
import Control.Monad.Reader
import Control.Monad.Trans
import Control.Monad.Trans.Maybe

type Config = M.Map String Int

getConfig :: String -> ReaderT Config Maybe Int
getConfig key = ReaderT $ \r -> M.lookup key r

readAll :: Config -> Maybe (Int, Int)
readAll m =
  let r = runReaderT $ do
      a <- getConfig "a"
      b <- getConfig "b"
      return (a, b)
  in r m

main :: IO ()
main = do
  putStrLn $ show (readAll $ M.fromList [("a", 3), ("b", 4)])

      

+4


source







All Articles