我有自定义类型
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
任何改进代码的建议都是受欢迎的。我只是想尽快完成它,因为这不是我的生成问题的解决方案,我需要设置一个树高的限制才能成功。
1条答案
按热度按时间sczxawaw1#
我猜你真正想要的是
所有"构建树"操作都有基于超时的重试。
要理解的关键是,"企图做X;如果在n毫秒内没有完成,重新开始"是IO的工作; IO是访问时间之类的东西的地方。(当然,当您只需要IO所提供的一部分内容时,您可以而且应该使用一些 Package 器。)
这是罚款;您可以在
GI
中访问IO
,您可能只需要访问lift
即可。也就是说,这里没有足够的信息来确切地说明如何做你想要的,而且我对自由单子效应系统比mtl变压器更熟悉...