haskell - 使用 ReaderT Maybe 还是 MaybeT Reader?

标签 haskell monad-transformers

我想写一个haskell程序来读取配置并做点什么。配置是 Data.Map并将被注入(inject)到 Reader 中。当我们找不到配置项时,应该中断读取。刚刚停止,不需要错误消息。所以我只想要一个Maybe monad(不是Either monad)。

问题是,我应该如何堆叠两个 monad,ReaderT MaybeMaybeT Reader ?

最佳答案

最后我想通了。他们俩都没事。

假设每个配置项的值只是一个 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))

无论是哪一种,我们都可以先做一些读取,然后根据读取是否返回 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 - 使用 ReaderT Maybe 还是 MaybeT Reader?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43840588/

相关文章:

design-patterns - 如何设计单子(monad)栈?

haskell - Yesod 条件子网站

haskell - Haskell 是用什么语言编写的?

haskell - 如果使用 HXT 在 Haskell 中解析 RSS 文件时标记丢失

haskell - 如果其中一个 monad 包装在 monad 转换器内,是否可以重用 monad 组合函数?

performance - 为什么嵌套的 MaybeT 会导致指数分配

javascript - 如何将 TaskT 与 Trampoline 的 monad 实例结合起来进行无堆栈异步计算?

haskell - 为 newtype-d CatchT (ST) 堆栈实现 PrimMonad

haskell - 特定函数名称 'it' 会发生什么?

haskell - 如何使用高阶函数实现这种基于IO的循环?