精彩的問題。
我知道沒有方法可以重新進入GHCi REPL,以便我們可以在CPS功能中使用它。也許其他人可以建議某種方式。
但是,我可以建議一個黑客。基本上,如果它基於IO monad,就可以利用併發性將CPS從內部轉出。
這裏的黑客:使用在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!
一個小型圖書館,以使自動化的黑客:
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"
來源
2017-02-23 21:42:02
chi
的'withSession'功能恰恰是提供會話的功能。通過在傳遞給'withSession'的函數體內操作'sess'參數來獲得會話。換句話說,如果你有'main = withSession ..',那麼只需在ghci提示符下鍵入'main'(或':main')即可運行該操作。至於「逐行評估延續」,你必須自己實現這個邏輯。 – user2407038
哇,很好的問題!能夠重新進入CPS風格的庫函數的GHCi repl確實很好。 – chi