具有IO和Maybe的Monad变压器

时间:2019-04-27 01:01:01

标签: haskell monad-transformers maybe io-monad

我正在尝试堆叠IO和Maymon,但是我对Monad转换器的理解不够,或者无法使用转换器。有人可以帮助我理解这一点吗?

f :: String -> Maybe String

main :: IO ()
main = do
  input <- getLine            -- IO String
  output <- f input           -- Maybe String (Can't extract because it is IO do block)
  writeFile "out.txt" output  -- gives error because writeFile expects output :: String

在上面的简化示例中,我有一个函数f返回了一个Maybe String,并且我想在IO do块中使用一种简洁的方法来提取它。我尝试过

f :: String -> MaybeT IO String

main :: IO ()
main = do
  input <- getLine              -- IO String
  output <- runMaybeT (f input) -- Extracts output :: Maybe String instead of String
  writeFile "out.txt" output    -- gives error because writeFile expects output :: String

这使我可以在Maybe String块的第二行中提取do,但是我需要从中提取字符串。有没有不用case来做到这一点的方法?

1 个答案:

答案 0 :(得分:4)

在您的第一个摘要中停留片刻。如果f inputMaybe String,并且您要将其结果传递给需要writeFile "out.txt"的{​​{1}},则需要处理String的可能性为f input。您不必从字面上使用案例陈述。例如:

    Prelude中的
  • Nothing被作为功能进行了案例分析;

  • maybe中的
  • fromMaybe可让您轻松提供默认值(如果对您的用例有意义);

  • 来自Data.Maybe
  • traverse_for_可用于静默忽略Data.Foldable-ness:

    Nothing

尽管如此,无论您选择做什么,都将涉及以某种方式处理for_ (f input) (writeFile "out.txt") -- Does nothing if `f input` is `Nothing`.

对于Nothing,您真的不需要在这里使用monad变压器。 MaybeT适用于您希望进行MaybeT IO计算之类的事情,但您还可以在其中包含Maybe计算的情况。如果IO已经满足您的要求,则无需向其添加基础的f :: String -> Maybe String层。