Cudowne pytanie.
Jestem świadomy braku metod, które mogą ponownie wprowadzić REPL GHCi, abyśmy mogli użyć tego w funkcjach CPS. Być może inni mogą sugerować w jakiś sposób.
Mogę jednak zaproponować hakera. Zasadniczo, można wykorzystać współbieżność, aby wyłączyć CPS na lewą stronę, jeśli opiera się na moninie IO, jak w tym przypadku.
Oto Hack: to wykorzystać w sesji 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!
Mała biblioteka zautomatyzować ten 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"
szybki test:
> (x, ctrl) <- startDebugCps testCps
testCps: begin
> x
"here's some string!"
> stopDebugCps ctrl
testCps: end
"some return value"
The 'withSession' funkcja jest właśnie funkcją, która zapewnia sesję. Dostajesz sesję, manipulując parametrem 'sess' w ciele funkcji przekazanej do' withSession'. Innymi słowy, jeśli masz 'main = withSession ..', po prostu wpisz' main' (lub ': main') w zachęcie ghci, aby uruchomić akcję. Na razie "oceń linię kontynuacji po linii", musisz sam wdrożyć tę logikę. – user2407038
Wow, wspaniałe pytanie! Naprawdę byłoby miło móc ponownie wprowadzić replikę GHCi dla funkcji biblioteki w stylu CPS. – chi