【问题标题】:How can I use REPL with CPS function?如何将 REPL 与 CPS 功能一起使用?
【发布时间】:2017-02-23 20:51:19
【问题描述】:

我刚刚遇到了withSession :: (Session -> IO a) -> IO awreq 包。我想逐行评估延续,但我找不到任何方法。

import Network.Wreq.Session as S
withSession $ \sess -> do
  res <- S.getWith opts sess "http://stackoverflow.com/questions"
  -- print res
  -- .. other things

在上面的 sn-p 中,我如何在 ghci 中评估 print res?换句话说,我可以在ghci中输入Session吗?

【问题讨论】:

  • withSession 函数正是提供会话的函数。您可以通过在传递给withSession 的函数体内操作sess 参数来“获取”会话。换句话说,如果您有main = withSession ..,那么只需在 ghci 提示符下键入main(或:main)即可运行该操作。至于“逐行评估延续”,您必须自己实现该逻辑。
  • 哇,好问题!能够为 CPS 风格的库函数重新输入 GHCi repl 确实很棒。

标签: haskell


【解决方案1】:

好问题。

我知道没有可以重新进入 GHCi REPL 的方法,因此我们可以在 CPS 函数中使用它。也许其他人可以提出一些建议。

但是,我可以建议一个 hack。基本上,如果它像本例那样基于 IO monad,则可以利用并发性将 CPS 彻底翻转。

这是 hack:在 GHCi 会话中使用它

> 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!

一个自动化 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"

快速测试:

> (x, ctrl) <- startDebugCps testCps
testCps: begin
> x
"here's some string!"
> stopDebugCps ctrl
testCps: end
"some return value"

【讨论】:

    猜你喜欢
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 2017-07-20
    • 2017-01-16
    • 2016-07-03
    • 1970-01-01
    • 2018-03-15
    相关资源
    最近更新 更多