haskell - 在haskell中绑定(bind)计算的运行时间

标签 haskell artificial-intelligence sleep thread-sleep

我正在用 Haskell 编写游戏 AI,我想在指定的时间内搜索游戏状态树(即,我总是希望 AI 花费 3 秒来决定要采取的行动)

我怎样才能用像 Haskell 这样的纯语言来做到这一点?我希望我需要深入研究线程等,但我希望尽可能地减少它。

最佳答案

一个想法:结合timeout (由@MathematicalOrchid 建议)带有来自SafeSemaphore 的可变变量每次您的进程计算部分结果时存储中间值:

import Control.Monad
import Control.Concurrent.MSampleVar
import System.Timeout

fac :: Integer -> Integer
fac 0 = 1
fac n = n * fac (n - 1)

tmo :: Int -> ((a -> IO ()) -> IO ()) -> IO (Maybe a)
tmo ms f = do
    mvar <- newSV Nothing
    timeout ms (f (writeSV mvar . (Just $!)))
    readSV mvar

longComp :: (Integer -> IO ()) -> IO ()
longComp save = let loop n = save (fac n) >> loop (n + 1)
                in loop 0

main :: IO ()
main = tmo 10000 longComp >>= print

传递给 tmo 的函数将 IO 作为它的第一个参数它可以用来保存中间结果的操作。如果超时,则返回最后保存的结果。结果被转换为WHNF,以便真正的计算发生在保存结果的线程中,而不是在从tmo返回时处理它的线程中。 .

在这个变体中,函数传递给 tmo必须保存它的输出,它不能返回它。但是很容易修改它,使其签名为 (a -> IO ()) -> IO a .

如果你想让事情更纯粹,我建议创建你自己的 monad 来封装这个想法而不让 IO出去。

更新:注意:

There is no guarantee that the exception will be delivered promptly, although the runtime will endeavour to ensure that arbitrary delays don't occur. In GHC, an exception can only be raised when a thread reaches a safe point, where a safe point is where memory allocation occurs. Some loops do not perform any memory allocation inside the loop and therefore cannot be interrupted by a throwTo.



(来自 throwTo 的文档)。在上面的示例中,fac不分配任何内存,因此对于大量内存不会立即中断。

更新:我基于这些想法创建了一个小型库,该库定义了一个用于计算的单子(monad),该单子(monad)可以在返回最终结果或因超时而死之前返回部分结果。见 https://github.com/ppetr/timeout-with-results

关于haskell - 在haskell中绑定(bind)计算的运行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13663261/

相关文章:

SKOS(语义网)的 Haskell 数据结构

list - Haskell 中的函数 snd 如何在过滤器中工作

JavaScript 计算机人工智能

java - Minimax Connect 4 AI 麻烦

c++ - n>0 的 Sleep(n) 是否会将 CPU 时间让给其他线程

database - Haskell Servant 将自定义数据传递给授权处理程序

haskell - 如何结合数据组合和 monad 转换器

python - 在 while 循环中使用 python 的 core.Clock.GetTime() 方法 : timing distortions?

c++ - 我应该使用图形库吗?

实时捕捉关键