序言
我正试图思考如何实际使用ContT和callCC来实现一些有用的东西。我在跟踪代码周围的信息和控制流时遇到了困难。(但是,这难道不是延续的意义吗?)
有很多不同的方法可以用这个单子和少数几个不太直接的组合子来移动。我要承认,我仍然对我对ContT工作方式的理解感到不舒服,但我要指出我迄今所读到的内容:
我想做的是发布一个psudo代码示例,然后问一些关于它的问题。这表示使用ContT的典型代码外观。
Psudo-代码
type MyMonad r = ContT r (State SomeState)
main = do
runState s_init $ runContT block print
block :: MyMonad r a0
block = do
before_callcc
output <- callCC $ \k -> do
rval <- inner_block
return rval
after_callcc问题
output的值和类型b在k类型中意味着什么?k的价值到哪里去了?inner_block什么时候运行?它看到的是哪一种状态?rval去哪里了?它的类型是什么?k和rval之间的关系是什么?k a)应用于inner_block,b)在after_callcc中,c)在block之外时,会发生什么?k摆脱blockk进入状态吗?颜色编码以便于阅读

发布于 2015-09-06 06:38:08
output的值和类型它将是与rval相同的类型。该值也将相同,除非inner_block使用k someValue来转义块的其余部分。在这种情况下,output将是someValue。
b在k类型中意味着什么?粗略地说,b可以理解为“任何东西”。也就是说,如果inner_block是
...
v <- k someValue
use v然后是v :: b。但是,k someValue将永远不会运行块的其余部分,因为它将立即退出callCC。因此,v的具体值将永远不会返回。正因为如此,v可以有任何类型:use是否需要String或Int并不重要--反正也不会执行。
k的价值到哪里去了?只要内部块运行k someValue,callCC就会以output的形式返回值,并跳过块的其余部分。
inner_block什么时候运行?它看到的是哪一种状态?它是在callCC被调用时运行的,并且看到了与我们在那一点上相同的状态。
rval去哪里了?它的类型是什么?转化为output。同样的类型。
k和rval之间的关系是什么?rval的类型与k的参数相同。
k a)应用于inner_block,b)在after_callcc中,c)在block之外时,会发生什么?( a)见上文。( b) k在after_callcc中超出了范围。( c)也超出了范围。
国家是“当前”状态。(我不知道你到底想要什么)
k摆脱block我想这里需要一个递归类型。下面是一个尝试:
import Control.Monad.Cont
import Control.Monad.State
import Control.Monad.Trans
type SomeState = String
type MyMonad r = ContT r (State SomeState)
newtype K a b r = K ((K a b r, a) -> MyMonad r b)
main = do
print $ flip runState "init" $ runContT block return
block :: MyMonad r Int
block = do
lift $ modify (++ ":start")
(K myK, output) <- callCC $ \k -> do
s <- lift $ get
lift $ modify (++ ":inner(" ++ show (length s) ++")")
return (K k, 10)
lift $ modify (++ ":output=" ++ show output)
s <- lift $ get
when (length s <50) $ myK (K myK, output+1)
return 5这个指纹
(5,"init:start:inner(10):output=10:output=11:output=12")k进入状态吗?我相信你也需要一个递归类型。
https://stackoverflow.com/questions/32419145
复制相似问题