首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在haskell中绑定计算的运行时

在haskell中绑定计算的运行时
EN

Stack Overflow用户
提问于 2012-12-02 04:09:16
回答 3查看 245关注 0票数 7

我正在用Haskell编写一个AI游戏,我想在游戏状态树中搜索一段指定的时间(即,我总是希望AI花3秒时间来决定下一步该走什么)。

我如何在像Haskell这样的纯语言中做到这一点呢?我希望我需要深入研究线程之类的东西,但我更愿意尽可能地将其最小化。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-02 05:55:25

一个想法是:将timeout (由@MathematicalOrchid建议)与SafeSemaphore中的可变变量相结合,以便在每次您的进程计算部分结果时存储中间值:

代码语言:javascript
复制
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

更新:请注意:

虽然运行库将尽力确保不会发生任意延迟,但不能保证异常会迅速传递。在GHC中,只有当线程达到安全点时才会引发异常,安全点是发生内存分配的地方。有些循环在循环内不执行任何内存分配,因此不能被throwTo中断。

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

更新:我基于这些想法创建了一个小型库,它定义了计算的单体,可以在返回最终结果之前返回部分结果,或者在超时时死亡。请参阅https://github.com/ppetr/timeout-with-results

票数 5
EN

Stack Overflow用户

发布于 2012-12-02 04:43:38

由于您要寻找的结果取决于时间,因此这不可避免地会涉及不纯代码。

看起来base包中的System.Timeout提供了在超时之前运行I/O计算的能力(根据leftaroundabout的评论)。因此,您所需要做的就是编写一个返回您感兴趣的结果的IO计算。然而..。棘手的部分是让IO操作实际计算结果,而不仅仅是返回未计算的结果。为此,我认为您需要来自Control.Exceptionevaluate

票数 3
EN

Stack Overflow用户

发布于 2012-12-02 05:48:23

System.Timeout是最好的选择。它有一个非常干净的界面,一点都不像你在摆弄线程。

搜索游戏空间听起来像是纯粹的计算,而System.Timeout运行的是IO操作,因此您需要将值包装在return中,并严格评估代码,使timeout不会在计算结果为WHNF后立即认为已返回答案。

这里有一个代码可能是什么样子的示例here,来自我遇到的一个类似的问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13663261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档