使IO成为MonadCont的实例有意义吗?

地球引擎

显然,由于其,sMonadCont比普通Monads更受限制,并具有更多功能callCC这意味着更少的实例,您可以做更多的事情。

查看的已定义实例时MonadCont,似乎其中列出的所有内容都需要或者ContContT已经存在的MonadCont实例。这意味着我们必须开始与一些Cont或者ContT,特别是不能把IOMonadCont

但是,我相信callCCIO上下文中使用它是有意义的,因此我们可以简化以下内容(从官方的Hackage页面 callCC示例中进行调整):

whatsYourName :: IO ()
whatsYourName = do
    name <- getLine
    let response = flip runCont id $ do
        callCC $ \exit -> do
            when (null name) (exit "You forgot to tell me your name!")
            return $ "Welcome, " ++ name ++ "!"            
    print response

进入

whatsYourName' :: IO ()
whatsYourName' = do
    name <- getLine
    response <- callCC $ \exit -> do
            when (null name) (exit "You forgot to tell me your name!")
            return $ "Welcome, " ++ name ++ "!"            
    print response

callCC更清洁的方式在do块中使用。

当然,要成为IO实例,MonadCont我们必须具有一定的魔力,因为callCCforIO意味着“用未来的计算来调用给定函数指定了在现实世界中下一步将发生什么”,因此只有解释器或编译器才能真正知道这意味着什么。另一方面,我没有看到任何理论上的理由认为它是可导入的,因为Scheme已经有很长一段时间了,并且创建这样的实例完全不需要更改语言。

可能的问题

我可以想到的一个因素是的语义callCC与适当的清除保证冲突。许多语言提供“ try ... finally”控制以进行适当的清理,而C ++的析构函数也保证了这一点。我不知道它是什么在Haskell,但如果callCC是供IO一个可以使用它从任何逃避IO需要清理涉及的范围内,所以提供一个sush将garantee成为不可能的,因为你可以看到在Ruby中会发生什么

意见讨论

@jozefg的答案非常好。我只想在这里写下我的意见。

  1. 的确MonadCont来自mtl。但这并不意味着unsafeCallCC如果MonadCont具有正确的定义在编译模块的范围内-XIOMonadCont并被设置,GHC或其他编译器将无法定义和定义实例

  2. 我已经讨论过异常安全性,很难确定这一点。但是,我认为Haskell已经拥有unsafePerformIO,它比基本上更加不安全unsafeCallCC

  3. callCC在大多数情况下,原因是过分强大的,应尽可能避免使用。但是,在我看来,可以使用延续传递样式来使懒惰评估变得明确,这可以帮助更好地理解程序,从而更容易找到可能的优化。当然,CPS不是MonadCont,但是使用CPS并将深层嵌套的内部函数转换为do表示法是自然的步骤。

丹尼尔·格拉泽(Daniel Gratzer)

我会说这是一个坏主意。首先,MonadCont是在MTL中。GHC对此一无所知,这意味着使编译器依赖于第三方库ick。

其次,callCC即使在一些非常知名的Schemer中也不受欢迎,主要是因为它使代码推理变得很痛苦!goto很难以相同的方式推理。特别是在Haskell时,我们不得不担心

  1. 异常安全吗?(这已经很难了)
  2. 它是callCC安全的吗?

最后,我们甚至不需要它。如果要使用延续和IO,请使用ContT IO,其功能同样强大。但是,我几乎保证可以用功能不强的东西代替它,例如monad-prompt延音是八角锤,十分之九,callCC过于强大,可以结合使用高阶函数和惰性来更愉快地表达。

例如,原型的用途之一callCC就是实现类似异常的东西,但是在Haskell中,我们只能使用monads:)(依赖于高阶函数和惰性)。

本质上,您的建议增加了复杂性,这意味着将MTL合并为基础,以及避免其他许多不愉快的事情liftIO

RE编辑

  1. 当然可以,但是那MonadCont当然不是实例了:)
  2. 这有点不同,unsafePerformIO它的用途是使副作用对其他任何人都不可见,因为您不能保证事情的执行方式或时间。

    如果是这种情况callCCIO,那么您可以使用Cont

  3. 连续传递样式很有用,我们可以用ConT r IO对我而言,这是棺材上最大的钉子,相对于仅使用现有库来解决困难且可能不安全的编译器黑客,我认为此想法没有任何好处。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使IO成为MonadCont的实例有意义吗?

来自分类Dev

PyGTK仍然有意义吗?

来自分类Dev

PyGTK仍然有意义吗?

来自分类Dev

base()的用法有意义吗?

来自分类Dev

属性的属性有意义吗?

来自分类Dev

是吗 超级/扩展byte []有意义吗?

来自分类Dev

使用R进行回归的randomForest有意义吗?

来自分类Dev

缩小和缩小都有意义吗?

来自分类Dev

Abs(无符号长整数)有意义吗?

来自分类Dev

单例模式对套接字有意义吗?

来自分类Dev

REM在边界半径上有意义吗?

来自分类Dev

阻止全局迭代器有意义吗?

来自分类Dev

static final String =“ something”-静态有意义吗?

来自分类Dev

python中的`def main(args):`有意义吗?

来自分类Dev

测试猫鼬模型有意义吗?

来自分类Dev

catch(...)总是有意义吗?

来自分类Dev

HTML元素上的rem单位有意义吗?

来自分类Dev

混合正则化符有意义吗?

来自分类Dev

Little Man Computer仍然有意义吗?

来自分类Dev

将btrfs放在lvm上有意义吗?

来自分类Dev

对ConcurrentDictionary进行排序有意义吗?

来自分类Dev

单例模式对Socket有意义吗?

来自分类Dev

static final String =“ something”-静态有意义吗?

来自分类Dev

交流定义宏有意义吗?

来自分类Dev

这种家庭网络配置有意义吗?

来自分类Dev

条件中的多余括号有意义吗?

来自分类Dev

这是没有意义的检查吗?

来自分类Dev

函数重载没有意义吗?

来自分类Dev

内联这个函数,有意义吗?