haskell 带IO的StateT超时

rur96b6h  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(182)

我有自定义类型

type GI a = StateT GenState IO a

其中GenState是生成随机树时的状态。生成树时,不能保证在合理的时间内终止。这就是为什么我想终止计算,并在超时后一遍又一遍地重新开始计算,直到给出结果。
所以我的问题是如何写一个函数的形式

tryGeneration :: GI a -> GI a
tryGeneraton action = ...

其中action是在几微秒内尝试的计算,并且如果超时,则从头开始该操作。
请记住,我是相当新的Monad变形金刚,我不能说我完全理解他们。
我尝试使用带有System.Timeout.timeout的lift,但没有成功

编辑:

谢谢大家的建议,我照着做了,在IO单子上完成了。

tryGenerationTime :: Int -> GenState -> GI a -> IO (a, GenState)
tryGenerationTime time state action = do
    (_, s') <- -- change the random state to not generate the same thing over and over
    res <- timeout time (runStateT action s') 
    case res of 
        Nothing -> tryGenerationTime time s' action
        Just r  -> return r

timeItT :: Int -> GI a -> GI a
timeItT time action = do
    state <- get
    (x, s') <- lift $ tryGenerationTime time state action
    put s'
    return x

任何改进代码的建议都是受欢迎的。我只是想尽快完成它,因为这不是我的生成问题的解决方案,我需要设置一个树高的限制才能成功。

sczxawaw

sczxawaw1#

我猜你真正想要的是

tryGeneration :: GI a -> IO a
tryGeneraton action = ...

所有"构建树"操作都有基于超时的重试。
要理解的关键是,"企图做X;如果在n毫秒内没有完成,重新开始"是IO的工作; IO是访问时间之类的东西的地方。(当然,当您只需要IO所提供的一部分内容时,您可以而且应该使用一些 Package 器。)
这是罚款;您可以在GI中访问IO,您可能只需要访问lift即可。
也就是说,这里没有足够的信息来确切地说明如何做你想要的,而且我对自由单子效应系统比mtl变压器更熟悉...

相关问题