我如何使用REPL和CPS功能? [英] How can I use REPL with CPS function?
问题描述
我刚刚遇到 withSession ::(Session - > IO a) - > IO a
wreq
包。我想逐行评估延续,但我无法找到任何方法。
import Network.Wreq。 Session作为S
withSession $ \sess - >
res< - S.getWith opts sesshttp://stackoverflow.com/questions
- print res
- ..其他东西
在上面的代码片段中,如何评估ghci中的 print res
?换句话说,我可以在ghci中获得 Session
类型吗?
精彩的问题。
我知道没有方法可以重新输入GHCi REPL,因此我们可以在CPS功能中使用它。也许其他人可以提出一些建议。
然而,我可以提出一个黑客攻击。基本上,如果是基于IO monad,就可以利用并发性将CPS从内部转出来。
下面是黑客攻击:在GHCi会话中使用它
> sess< - newEmptyMVar :: IO(MVar Session)
>停止< - newEmptyMVar :: IO(MVar())
> forkIO $ withSession $ \s - > putMVar sess s>> takeMVar stop
> s< - takeMVar sess
> - 在这里使用,就好像你在里面withSession
>让s =() - 建议
> putMVar stop()
> - 我们现在在Session的外面,不要试图在这里访问!
一个自动化黑客攻击的小型库:
< pre $ data CPSControl b = CPSControl(MVar())(MVar b)
startDebugCps ::((a - > IO()) - > IO b) - > IO(a,CPSControl b)
startDebugCps cps = do
cpsVal< - newEmptyMVar
retVal< - newEmptyMVar
stop< - newEmptyMVar
_< - forkIO $ do
x< - cps $ \c - > putMVar cpsVal c>> takeMVar stop
putMVar retVal x
s < - takeMVar cpsVal
return(s,CPSControl stop retVal)
stopDebugCps :: CPSControl b - > IO b
stopDebugCps(CPSControl stop retVal)= do
putMVar stop()
takeMVar retVal
testCps ::(String - > IO()) - > ; IO String
testCps act = do
putStrLntestCps:begin
act这里有一些字符串!
putStrLntestCps:end
返回一些返回值
A快速测试:
> (x,ctrl)< - startDebugCps testCps
testCps:begin
> x
这是一些字符串!
> stopDebugCps ctrl
testCps:end
一些返回值
I've just encountered withSession :: (Session -> IO a) -> IO a
of wreq
package. I want to evaluate the continuation line by line, but I can't find any way for this.
import Network.Wreq.Session as S
withSession $ \sess -> do
res <- S.getWith opts sess "http://stackoverflow.com/questions"
-- print res
-- .. other things
In above snippet how can I evaluate print res
in ghci? In other words, can I get Session
type in ghci?
Wonderful question.
I am aware of no methods that can re-enter the GHCi REPL, so that we can use that in CPS functions. Perhaps others can suggest some way.
However, I can suggest an hack. Basically, one can exploit concurrency to turn CPS inside out, if it is based on the IO monad as in this case.
Here's the hack: use this in a GHCi session
> sess <- newEmptyMVar :: IO (MVar Session)
> stop <- newEmptyMVar :: IO (MVar ())
> forkIO $ withSession $ \s -> putMVar sess s >> takeMVar stop
> s <- takeMVar sess
> -- use s here as if you were inside withSession
> let s = () -- recommended
> putMVar stop ()
> -- we are now "outside" withSession, don't try to access s here!
A small library to automatize the hack:
data CPSControl b = CPSControl (MVar ()) (MVar b)
startDebugCps :: ((a -> IO ()) -> IO b) -> IO (a, CPSControl b)
startDebugCps cps = do
cpsVal <- newEmptyMVar
retVal <- newEmptyMVar
stop <- newEmptyMVar
_ <- forkIO $ do
x <- cps $ \c -> putMVar cpsVal c >> takeMVar stop
putMVar retVal x
s <- takeMVar cpsVal
return (s, CPSControl stop retVal)
stopDebugCps :: CPSControl b -> IO b
stopDebugCps (CPSControl stop retVal) = do
putMVar stop ()
takeMVar retVal
testCps :: (String -> IO ()) -> IO String
testCps act = do
putStrLn "testCps: begin"
act "here's some string!"
putStrLn "testCps: end"
return "some return value"
A quick test:
> (x, ctrl) <- startDebugCps testCps
testCps: begin
> x
"here's some string!"
> stopDebugCps ctrl
testCps: end
"some return value"
这篇关于我如何使用REPL和CPS功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!