有没有人知道只允许一定时间执行功能的功能。像这样的类型签名的东西。
limited::Int->(a->b)->a->IO (Maybe b)
我想不出如何实现,我找不到它。我问的原因是我要列出所有可能的Brainfuck程序,我想过滤那些花费太长时间的程序。
答案 0 :(得分:20)
System.Timeout中有a dedicated function:
timeout :: Int -> IO a -> IO (Maybe a)
按照你写的方式,只需使用
limited t f x = timeout t $ do
let y = f x
y `seq` return y
请记住,Haskell的懒惰意味着任何值都是其他语言可能称之为“零参数的记忆函数”,所以你真的不需要(a->b) -> a ->
。
答案 1 :(得分:9)
使用async
包,我们可以race
个帖子。
import Control.Applicative
import Control.Concurrent
import Control.Concurrent.Async
limited :: Int -> (a -> b) -> a -> IO (Maybe a)
limited n f a = isLeft <$> race (return $! f a) (threadDelay n)
where isLeft (Left a) = Just a
isLeft _ = Nothing
race
在不同的线程中运行两个IO
计算,并返回“获胜”中的任何一个,所以我们只是将我们的线程与threadDelay
进行竞争。
请注意,我们使用($!)
seq
结果f a
。如果我们不这样做,那么Left
线程总是会赢,并且当您查看它时,计算实际上会发生在主线程中。