我正在尝试堆叠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
来做到这一点的方法?
答案 0 :(得分:4)
在您的第一个摘要中停留片刻。如果f input
是Maybe String
,并且您要将其结果传递给需要writeFile "out.txt"
的{{1}},则需要处理String
的可能性为f input
。您不必从字面上使用案例陈述。例如:
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
层。