停止/腌制/取消/恢复计算

Sib*_*ibi 5 haskell computation

是否有任何Haskell停止/腌制/取消/恢复计算的方式?

关于这一点的一些相关讨论似乎在这里发生,但没有提出适当的解决方案.这个讨论还很旧.

如果存在某种类型的事件系统用于触发计算的停止和恢复状态,那也是好的.

J. *_*son 3

实现此目的的一种(部分)方法是在Partiality 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)
Run Code Online (Sandbox Code Playgroud)

使用它,我们可以创建返回 monad 的计算Partial并控制它们的评估。

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
Run Code Online (Sandbox Code Playgroud)

在这里,我们可以使用runN部分执行计算,最多在大多数n步骤后停止并返回新的、计算更多的 thunk 或实际结果。我们也可以把谨慎抛在脑后,run永远等待Partialmonad 执行。

有趣的是,在 monad 中编写内容Partial可以让您对程序的终止进行一些控制。只要Step某些计算中的每个都f终止,那么也runN n f总是终止。这是我们想要函数暂停的一种属性。

使用 monad 的主要挑战Partial是它必须影响计算的每一步才能工作——其中的任何纯计算最多需要一个Step。另一个密切相关的问题是您必须Step手动用 s 注释代码。最后,Steps 没有特别保证大小相似或与时钟时间有任何关系。

最后一个问题至少可以通过工作线程的一些并发编程来解决,该工作线程可以接收信号以在执行计算时“尽快暂停” Partial

最后,非常值得注意的是,Partial ~ Free Identity它提供了对 s 功能的很好的概括Partial,这使得 s 的注释变得Step更加容易。