是否有任何 Haskell 方法来停止/pickling/unpickling/恢复计算?
似乎发生了一些相关讨论here但没有提出适当的解决方案。而且这个讨论已经过时了。
如果有某种类型的事件系统来触发计算的停止和恢复状态,那就太好了。
最佳答案
实现此目的的一种(部分)方法是在 Partial
ity monad 中进行操作。
data Partial a = Done a | Step (Partial a)
deriving Functor
instance Monad Partial where
return = Done
Done x >>= f = f x
Step p >>= f = Step (p >>= f)
使用它,我们可以创建在 Partial
monad 中返回的计算并控制它们的评估。
reversePartially :: [a] -> Partial [a]
reversePartially = rev [] where
rev acc [] = Done acc
rev acc (x:xs) = Step (rev (x:acc) xs)
runN :: Int -> Partial a -> Either (Partial a) a
runN _ (Done a) = Right a
runN 0 (Step p) = Left p
runN n (Step p) = runN (pred n) p
run :: Partial a -> a
run (Step p) = run p
run (Done a) = a
这里我们可以使用runN
来部分执行计算,最多在n
步后停止并返回新的、经过更多计算的thunk或实际结果。我们也可以不顾一切,使用 run
永远等待 Partial
monad 执行。
有趣的是,在 Partial
monad 中编写内容可以让您对程序的终止进行一些控制。只要某些计算f
中的每个Step
终止,那么runN n f
也总是终止。这是我们想要用于函数暂停的一种属性。
使用 Partial
monad 的主要挑战是它必须影响计算的每一步才能工作——其中的任何纯计算最多需要一个 Step
。另一个密切相关的问题是您必须手动使用 Step
注释代码。最后,Step
没有特别保证大小相似或与时钟时间有任何关系。
最后一个问题至少可以通过工作线程的一些并发编程来解决,该工作线程可以在执行部分
计算时接收“尽快暂停”的信号。
最后,非常值得注意的是 Partial ~ Free Identity
,它很好地概括了 Partial
的功能,可以对 Step
进行注释稍微容易一些。
关于haskell - 停止/Pickling/Unpickling/恢复计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20911363/