gpt4 book ai didi

haskell - Haskell IO 的 MonadPlus 定义

转载 作者:行者123 更新时间:2023-12-02 15:44:00 27 4
gpt4 key购买 nike

我只是快速编写了一些代码,我想使用 guard function在 IO Monad 中。然而,有no definition of MonadPlus for IO这意味着我们不能在 IO 领域使用守卫。我见过an example of using the MabyeT transformer to use guard in the Maybe Monad然后解除所有 IO 操作,但如果不需要的话,我真的不想这样做。

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

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 中获得保护函数(或类似的函数)。或者也许我做错了;有没有更好的方法在上面的函数中编写帮助消息?谢谢。

(P.S.我可以使用 if-then-else 语句,但它似乎在某种程度上违背了这一点。更不用说对于很多选项来说,它会导致大量的嵌套。)

最佳答案

考虑 MonadPlus 的定义:

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 中找到实现上述内容所需的一切。

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

关于haskell - Haskell IO 的 MonadPlus 定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4504489/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com