I want to write a haskell program reading config and do something. The config is a Data.Map
and will be injected into a Reader. And when we can't find a config item, the reading should be interrupted. Just stopped, no error messages are required. So I just want a Maybe monad(not Either monad).
The problem is, how should I stack the two monads, ReaderT Maybe
or MaybeT Reader
?
Finally I figure it out. Both of them are OK.
Assume every config item's value is just an Int.
The ReaderT ConfigMap Maybe Int
will have a value like:
ReaderT (\r -> Just 123)
or
ReaderT (\r -> Nothing)
The MaybeT (Reader ConfigMap) Int
will have a value like:
MaybeT (Reader (\r -> Just 123))
or:
MaybeT (Reader (\r -> Nothing))
With either, we can first do some read, then decide whether we should continue according whether the read returns a Nothing
. The values have different outer shapes but the same functionality.
My little demo 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)])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With