関数を実行するのに一定の時間しかかからない関数を知っている人はいますか?このようなタイプの署名を持つもの。評価のHaskellの時間制限
limited::Int->(a->b)->a->IO (Maybe b)
実装方法を考えることができず、見つからなかった。私が尋ねる理由は、可能なすべてのBrainfuckプログラムのリストを作成するつもりであり、あまりにも時間がかかるものを除外したいのです。
関数を実行するのに一定の時間しかかからない関数を知っている人はいますか?このようなタイプの署名を持つもの。評価のHaskellの時間制限
limited::Int->(a->b)->a->IO (Maybe b)
実装方法を考えることができず、見つからなかった。私が尋ねる理由は、可能なすべてのBrainfuckプログラムのリストを作成するつもりであり、あまりにも時間がかかるものを除外したいのです。
System.Timeoutからa dedicated functionあります:
timeout :: Int -> IO a -> IO (Maybe a)
だけでHaskellの怠慢は、任意の値を他の言語には「memoised呼ぶかもしれない何をされることを意味することに注意してください
limited t f x = timeout t $ do
let y = f x
y `seq` return y
を使用し、それをあなたが書いた方法を持っているために0引数の関数 "となるので、実際には(a->b) -> a ->
は必要ありません。
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
は別のスレッドとリターンの2つのIO
計算方の一つの「勝利」を実行しますので、我々はちょうどthreadDelay
に対する私たちのスレッドをレース。
($!)
〜seq
の結果はf a
です。我々がしない場合、Left
スレッドは常に勝つので、実際にはメインスレッドで計算が行われます。
私はそれが存在することは知らなかった。 –
'制限付きt f x =タイムアウトt(return $!f x)' –
さらに良い: 'timeout t $ evaluate(fx)'( 'evaluate'は' Control.Exception'で定義されています) –