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
?
source to share
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)])
source to share