首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell IO的MonadPlus定义

Haskell IO的MonadPlus定义
EN

Stack Overflow用户
提问于 2010-12-22 06:18:42
回答 3查看 2.2K关注 0票数 14

我只是在写一小段代码,我想在IO Monad中使用guard function。然而,存在no definition of MonadPlus for IO,这意味着我们不能在IO域中使用guard。我已经看到了an example of using the MabyeT transformer to use guard in the Maybe Monad,然后提升了所有IO操作,但如果没有必要的话,我并不真的想这样做。

我想要的一些例子可能是:

代码语言:javascript
复制
handleFlags :: [Flag] -> IO ()
handleFlags flags = do
    when (Help `elem` flags) (putStrLn "Usage: program_name options...")
    guard (Help `elem` flags)
    ... do stuff ...
    return ()

我想知道是否有一种很好的方法可以通过声明MonadPlus或其他方式在IO Monad中获得一个守卫函数(或类似的函数)。或者我可能做错了;有没有更好的方法在上面的函数中编写帮助消息?谢谢。

(附注:我可以使用if-then-else语句,但它似乎以某种方式违背了要点。更不用说,对于许多选项,这将导致大量的嵌套。)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-12-22 07:06:58

考虑MonadPlus的定义

代码语言:javascript
复制
class Monad m => MonadPlus m where
    mzero :: m a 
    mplus :: m a -> m a -> m a

您将如何为IO实现mzeroIO a类型的值表示返回a类型的内容的IO计算,因此mzero必须是返回任何可能类型的内容的IO计算。显然,没有办法为某个任意类型变出一个值,而且与Maybe不同的是,我们没有可以使用的“空”构造函数,因此mzero必然表示永远不返回的IO计算。

如何编写永远不返回的IO计算?基本上,要么进入无限循环,要么抛出运行时错误。前者的效用令人怀疑,因此后者就是你所坚持的。

简而言之,要为IO编写一个MonadPlus实例,您需要做的是:让mzero抛出一个运行时异常,并让mplus在捕获mzero抛出的任何异常时计算其第一个参数。如果未引发异常,则返回结果。如果引发异常,则在忽略异常的情况下计算mplus的第二个参数。

也就是说,运行时异常通常被认为是不可取的,所以在走这条路之前我会犹豫。如果您确实想这样做(并且不介意增加您的程序在运行时崩溃的可能性),您可以找到在Control.Exception中实现上述内容所需的一切。

在实践中,如果我想要对一元表达式求值的结果进行大量的guard运算,或者如果大多数条件依赖于作为函数参数提供的纯值(示例中的标志是),我可能会使用一元转换器方法,就像@Anthony的答案中那样使用模式保护。

票数 24
EN

Stack Overflow用户

发布于 2010-12-22 07:05:50

我和守卫一起做这类事情。

代码语言:javascript
复制
handleFlags :: [Flag] -> IO ()
handleFlags flags
  | Help `elem` flags = putStrLn "Usage: program_name options..."
  | otherwise = return ()
票数 8
EN

Stack Overflow用户

发布于 2016-05-01 23:17:41

有一些函数正是为此而设计的:在Control.Monad中,函数when和它的对应函数unless。安东尼的答案可以重写为:

代码语言:javascript
复制
handleFlags :: [Flag] -> IO ()
handleFlags flags =
    when (Help `elem` flags) $ putStrLn "Usage: program_name options..."

规格:

代码语言:javascript
复制
when :: (Applicative m) => Bool -> m () -> m ()
unless bool = when (not bool)

Link to docs on hackage.haskell.org

如果需要更多,这里有一个link to another package, specifically monad-oriented and with several more utilities: Control.Monad.IfElse

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4504489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档