使用 ReaderT Maybe 或 MaybeT Reader?
Use ReaderT Maybe or MaybeT Reader?
我想写一个 haskell 程序读取配置并做一些事情。配置是 Data.Map
,将被注入 Reader。而当我们找不到配置项时,应该中断读取。刚刚停止,不需要错误消息。所以我只想要一个 Maybe monad(不是 Either monad)。
问题是,我应该如何堆叠两个 monad,ReaderT Maybe
或 MaybeT Reader
?
我终于明白了。两个都OK。
假设每个配置项的值只是一个 Int。
ReaderT ConfigMap Maybe Int
的值类似于:
ReaderT (\r -> Just 123)
或
ReaderT (\r -> Nothing)
MaybeT (Reader ConfigMap) Int
的值类似于:
MaybeT (Reader (\r -> Just 123))
或:
MaybeT (Reader (\r -> Nothing))
不管是哪一个,我们都可以先做一些读取,然后根据是否读取returns和Nothing
来决定是否继续。这些值具有不同的外形但具有相同的功能。
我的小演示:
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)])
我的第二个演示:
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)])
我想写一个 haskell 程序读取配置并做一些事情。配置是 Data.Map
,将被注入 Reader。而当我们找不到配置项时,应该中断读取。刚刚停止,不需要错误消息。所以我只想要一个 Maybe monad(不是 Either monad)。
问题是,我应该如何堆叠两个 monad,ReaderT Maybe
或 MaybeT Reader
?
我终于明白了。两个都OK。
假设每个配置项的值只是一个 Int。
ReaderT ConfigMap Maybe Int
的值类似于:
ReaderT (\r -> Just 123)
或
ReaderT (\r -> Nothing)
MaybeT (Reader ConfigMap) Int
的值类似于:
MaybeT (Reader (\r -> Just 123))
或:
MaybeT (Reader (\r -> Nothing))
不管是哪一个,我们都可以先做一些读取,然后根据是否读取returns和Nothing
来决定是否继续。这些值具有不同的外形但具有相同的功能。
我的小演示:
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)])
我的第二个演示:
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)])