显然,由于其,sMonadCont
比普通Monad
s更受限制,并具有更多功能callCC
。这意味着更少的实例,您可以做更多的事情。
查看的已定义实例时MonadCont
,似乎其中列出的所有内容都需要或者Cont
或ContT
已经存在的MonadCont
实例。这意味着我们必须开始与一些Cont
或者ContT
,特别是不能把IO
成MonadCont
。
但是,我相信callCC
在IO
上下文中使用它是有意义的,因此我们可以简化以下内容(从官方的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
我们必须具有一定的魔力,因为callCC
forIO
意味着“用未来的计算来调用给定函数指定了在现实世界中下一步将发生什么”,因此只有解释器或编译器才能真正知道这意味着什么。另一方面,我没有看到任何理论上的理由认为它是可导入的,因为Scheme已经有很长一段时间了,并且创建这样的实例完全不需要更改语言。
可能的问题
我可以想到的一个因素是的语义callCC
与适当的清除保证冲突。许多语言提供“ try ... finally”控制以进行适当的清理,而C ++的析构函数也保证了这一点。我不知道它是什么在Haskell,但如果callCC
是供IO
一个可以使用它从任何逃避IO
需要清理涉及的范围内,所以提供一个sush将garantee成为不可能的,因为你可以看到在Ruby中会发生什么。
意见讨论
@jozefg的答案非常好。我只想在这里写下我的意见。
的确MonadCont
来自mtl。但这并不意味着unsafeCallCC
如果MonadCont
具有正确的定义在编译模块的范围内-XIOMonadCont
并被设置,GHC或其他编译器将无法定义和定义实例。
我已经讨论过异常安全性,很难确定这一点。但是,我认为Haskell已经拥有unsafePerformIO
,它比基本上更加不安全unsafeCallCC
。
callCC
在大多数情况下,原因是过分强大的,应尽可能避免使用。但是,在我看来,可以使用延续传递样式来使懒惰评估变得明确,这可以帮助更好地理解程序,从而更容易找到可能的优化。当然,CPS不是MonadCont
,但是使用CPS并将深层嵌套的内部函数转换为do表示法是自然的步骤。
我会说这是一个坏主意。首先,MonadCont
是在MTL中。GHC对此一无所知,这意味着使编译器依赖于第三方库ick。
其次,callCC
即使在一些非常知名的Schemer中也不受欢迎,主要是因为它使代码推理变得很痛苦!goto
很难以相同的方式推理。特别是在Haskell时,我们不得不担心
callCC
安全的吗?最后,我们甚至不需要它。如果要使用延续和IO,请使用ContT IO
,其功能同样强大。但是,我几乎保证可以用功能不强的东西代替它,例如monad-prompt
。延音是八角锤,十分之九,callCC
过于强大,可以结合使用高阶函数和惰性来更愉快地表达。
例如,原型的用途之一callCC
就是实现类似异常的东西,但是在Haskell中,我们只能使用monads:)(依赖于高阶函数和惰性)。
本质上,您的建议增加了复杂性,这意味着将MTL合并为基础,以及避免其他许多不愉快的事情liftIO
。
MonadCont
当然不是实例了:)这有点不同,unsafePerformIO
它的用途是使副作用对其他任何人都不可见,因为您不能保证事情的执行方式或时间。
如果是这种情况callCCIO
,那么您可以使用Cont
!
连续传递样式很有用,我们可以用ConT r IO
!对我而言,这是棺材上最大的钉子,相对于仅使用现有库来解决困难且可能不安全的编译器黑客,我认为此想法没有任何好处。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句