条件计算可能(IO())

时间:2016-01-10 22:06:46

标签: haskell

我对Haskell相当新,我想表达可能会或可能不会发生的IO动作的概念。

Network.URI提供了解析URI的功能

parseURI :: String -> Maybe URI

在我的主要功能中,我从用户那里获得输入

main :: IO ()
main = do
  url <- getLine
  getResource url

并使用parseURI函数

getResource :: String -> Maybe (IO ())
getResource url = parseURI url >>= doStuff

doStuff :: URI -> Maybe (IO ())
doStuff = undefined

正如您所看到的,我想使用>>=来避免case of级联,我会处理Maybes。

我已经设法通过将IO嵌入到Maybe中来实现。我想表达可能会或可能不会发生的IO操作的情况。我该怎么用?我肯定不是第一个遇到这个问题的人。我已经研究过MaybeT和MonadIO,但我不确定这是我需要的。

具体来说,如果我将doStuff移到MaybeT IO (),我仍然坚持使用parseURI url :: Maybe String。如果我现在将其提升到MaybeT,我会MaybeT Maybe String,但这与doStuff :: MaybeT IO ()无法匹配

我希望看起来更好(如果可能的话)并了解什么是正确的方向以及使用哪些主流工具。

感谢您的时间和建议。

1 个答案:

答案 0 :(得分:3)

首先关闭:可能发生或不发生IO ()行为的类型可能只是IO ():您不关心结果,或者是否成功,您只是希望它在可能的情况下执行

如果你关心成功,那么有两种选择。

  • Maybe (IO ())是动作的类型或不是动作,但是否是透明的“纯值”。即,如果您在顶层有Maybe (IO ())值,则您可以确定某个操作是否可能发生而无需先实际执行任何IO 。但是这不是一个值的类型,你首先必须做一些IO来确定关键动作是否会发生,因为为了绑定任何IO,你必须在Just分支中Maybe!因此,如果成功取决于用户提供的字符串,那么这对您来说可能是正确的类型。
  • IO (Maybe ())IO操作的类型,可以执行确定要采取的操作所需的任何操作。该类型实际上等同于IO Bool - IO操作返回一些指示标记。您可以指定 Just ()表示某些关键操作已经发生,而Nothing表示它没有,但是没有办法真正从签名。

MaybeT IO ()等同于后者,实际上可能是您应用程序的最佳类型。只是,你需要正确地进行变压器升降! lift从变换器堆栈中的 down 开始执行操作,直到该堆栈的顶部。因此lift!例如,您需要将IO正常的getLine :: IO String操作提升到MaybeT IO堆栈中:

lift getLine :: MaybeT IO String

但是,如果您有一个纯Maybe值,则需要“支持”它以获得MaybeT IO。最简单的方法是直接使用MaybeT构造函数。

getResource :: String -> MaybeT IO ()
getResource url = MaybeT (return $ parseURI url) >>= doStuff

doStuff :: URI -> MaybeT IO ()
doStuff = undefined