Zor*_*jak 10 haskell operational continuation
我有一些简单的原始操作,例如:
在的情况下,操作单子:
import Control.Monad.Operational
type Process a = Program ProcessI a
data ProcessI a where
GetInput :: ProcessI String
Dump :: String -> ProcessI ()
getInput :: Process String
getInput = singleton GetInput
dump :: String -> Process ()
dump = singleton . Dump
Run Code Online (Sandbox Code Playgroud)
或者在免费 monad的情况下:
import Control.Monad.Free
type Process = Free ProcessF
data ProcessF a
= GetInput (String -> a)
| Dump String a
deriving (Functor)
getInput :: Process String
getInput = liftF $ GetInput id
dump :: String -> Process ()
dump s = liftF $ Dump s ()
Run Code Online (Sandbox Code Playgroud)
两种情况下的简单操作都是相同的,例如:
proc1 :: Process ()
proc1 = forever $ do
a <- getInput
b <- getInput
dump $ a ++ b
dump $ b ++ a
Run Code Online (Sandbox Code Playgroud)
我的问题是:是否有可能以某种方式解释进程(proc1),将某个步骤中的连续序列化为磁盘,然后在下一个程序执行期间恢复?你能举个例子吗?
如果不可能,那么最接近的解决方法是什么?
我想只在下一个输入可用时启动程序,应用继续输入,然后解释直到下一个"getInput"并退出.
我可以想象这个场景记录所有输入,然后在继续之前重放它们以使系统处于相同状态,但在这种情况下,日志会无限制地增长.我找不到任何方法来在解释器中执行日志,因为没有可能比较continuation(没有EQ实例)并且进程是无限的.
我认为,有两个问题:
continuation可以包含任意数据类型
continuation可以包含函数(即闭包)
特别是考虑到第二个约束条件,可能没有简单的方法可以完全按照您的要求进行操作.
关于Can Haskell函数的讨论是序列化的吗?指向一个名为packman的库.从自述文件:
...该功能可用于通过记忆(跨不同程序运行)优化程序,以及检查所选位置的程序执行.两种用途都在上面链接的幻灯片组中举例说明.
(我想,它提到的幻灯片.)
这种方法的限制是不是所有类型的数据可以(或应该!)被序列化,特别是可变类型一样IORef,MVar和STM-相关的类型,有时这些最终在的thunk和封锁导致运行时异常.
此外,库依赖于序列化延续由创建它的相同二进制文件占用,这可能是您的应用程序的真正问题,也可能不是.
因此,您可以使用稍微有限且复杂的方法获得或多或少的所需内容,packman或者您可以编写自己的自定义逻辑,该自定义逻辑可以自定义类型以及捕获您关注的所有信息的自定义类型.