ContT Monad:将各个部分放在一起
The ContT Monad: Putting the pieces together
序言
我正在努力思考如何实际使用 ContT
和 callCC
来做一些有用的事情。我在跟踪代码周围的信息和控制流时遇到了问题。 (但是,这不是继续的意义吗?)
有很多不同的方法可以使用这个 monad 和一小部分不是很直接的组合器来移动片段。我承认我对我对 ContT 工作原理的理解仍然不自在,但我会指出我目前所读的内容:
- Haskell/Continuation passing style
- How and why does the Haskell Cont monad work?
- Understanding Haskell callCC examples
- Goto in Haskell: Can anyone explain this seemingly insane effect of continuation monad usage?
- How to interpret callCC in Haskell?
- Parsec Generally(让我走上这条路的文章)
我想做的是post一个伪代码示例,然后问一些关于它的问题。这表示使用 ContT
的典型代码外观
伪代码
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
之外时会发生什么?
- 以上每个状态的版本是什么?
- 我需要做什么才能从
block
中获得 k
?
- 我可以把
k
放入状态吗?
颜色编码以便于阅读
- What determines the value and type of
output
?
它将与 rval
的类型相同。该值也将相同,除非 inner_block
使用 k someValue
转义块的其余部分。在这种情况下,output
将是 someValue
。
- What does the
b
mean in the type of k
?
粗略地说,b
可以理解为"anything at all"。也就是说,如果inner_block
是
...
v <- k someValue
use v
然后 v :: b
。但是,k someValue
永远不会 运行 块的其余部分,因为它会立即退出 callCC
。因此,不会返回 v
的具体值。因此 v
可以有任何类型:use
是否需要 String
或 Int
并不重要——它不会被执行。
- Where does the value given to
k
go?
一旦内部块 运行s k someValue
值由 callCC
返回为 output
,块的其余部分将被跳过。
- When is
inner_block
run? What version of the state does it see?
它是 运行,因为 callCC
被调用,并且看到的状态与我们当时的状态相同。
- Where does
rval
go and what its type?
进入output
。同款。
- What is the relationship between
k
and rval
?
rval
与 k
.
的参数类型相同
- What happens when I apply
k
a) in inner_block
, b) in after_callcc
, c) outside of block
?
a) 见上文。
b) k
超出了 after_callcc
的范围。
c) 也不在范围内。
- What is the version of the state in each of the above?
该州是 "current" 州。 (我不确定你到底想问什么)
- What do I need to do to get
k
out of 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")
- Can I put
k
into the state?
我相信你也需要一个递归类型。
序言
我正在努力思考如何实际使用 ContT
和 callCC
来做一些有用的事情。我在跟踪代码周围的信息和控制流时遇到了问题。 (但是,这不是继续的意义吗?)
有很多不同的方法可以使用这个 monad 和一小部分不是很直接的组合器来移动片段。我承认我对我对 ContT 工作原理的理解仍然不自在,但我会指出我目前所读的内容:
- Haskell/Continuation passing style
- How and why does the Haskell Cont monad work?
- Understanding Haskell callCC examples
- Goto in Haskell: Can anyone explain this seemingly insane effect of continuation monad usage?
- How to interpret callCC in Haskell?
- Parsec Generally(让我走上这条路的文章)
我想做的是post一个伪代码示例,然后问一些关于它的问题。这表示使用 ContT
的典型代码外观伪代码
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
之外时会发生什么? - 以上每个状态的版本是什么?
- 我需要做什么才能从
block
中获得k
? - 我可以把
k
放入状态吗?
颜色编码以便于阅读
- What determines the value and type of
output
?
它将与 rval
的类型相同。该值也将相同,除非 inner_block
使用 k someValue
转义块的其余部分。在这种情况下,output
将是 someValue
。
- What does the
b
mean in the type ofk
?
粗略地说,b
可以理解为"anything at all"。也就是说,如果inner_block
是
...
v <- k someValue
use v
然后 v :: b
。但是,k someValue
永远不会 运行 块的其余部分,因为它会立即退出 callCC
。因此,不会返回 v
的具体值。因此 v
可以有任何类型:use
是否需要 String
或 Int
并不重要——它不会被执行。
- Where does the value given to
k
go?
一旦内部块 运行s k someValue
值由 callCC
返回为 output
,块的其余部分将被跳过。
- When is
inner_block
run? What version of the state does it see?
它是 运行,因为 callCC
被调用,并且看到的状态与我们当时的状态相同。
- Where does
rval
go and what its type?
进入output
。同款。
- What is the relationship between
k
andrval
?
rval
与 k
.
- What happens when I apply
k
a) ininner_block
, b) inafter_callcc
, c) outside ofblock
?
a) 见上文。
b) k
超出了 after_callcc
的范围。
c) 也不在范围内。
- What is the version of the state in each of the above?
该州是 "current" 州。 (我不确定你到底想问什么)
- What do I need to do to get
k
out ofblock
?
我想这里需要递归类型。这是一个尝试:
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")
- Can I put
k
into the state?
我相信你也需要一个递归类型。