切断懒惰列表生成

Cha*_*ham 5 haskell functional-programming

我想知道是否有人对如何制作一个能够获取列表的函数有任何见解,并且只返回可以在x时间内生成的术语.

例如,我有一个函数需要10分钟才能返回几个术语.我不想猜测我能生成多少个术语(使用x),我只想将无限列表输入到我的低效函数中,并有一个单独的函数来决定何时超时.

所以像这样: [5,7,10] = takeUntilTime (10 sec) . inefficientFunction $ [1..]

我对haskell很新,但我想我可以编写该函数来在每个新术语生成后检查计时器,如果时间已经过去就停止.

但是,如果第四个任期需要永恒呢?有没有办法阻止lowfficientFunction完成第四个任期的生成,即使它已经开始了?

我对一个直截了当的答案没有寄予厚望,但我对此表示赞赏.谢谢.

eph*_*ent 10

没有经过多次测试,但这似乎有效,至少在很小的范围内.

import Control.Concurrent
import Control.Exception
import Control.Monad

takeUntilTime :: Int -> [a] -> IO [a]
takeUntilTime limit list = do
    me <- myThreadId
    bracket (forkIO $ threadDelay limit >> throwTo me NonTermination) killThread
        . const $ tryTake list
  where
    (/:/) = liftM2 (:)
    tryTake list = handle (\NonTermination -> return []) $
        case list of
            [] -> return []
            x:xs -> evaluate x /:/ tryTake xs
Run Code Online (Sandbox Code Playgroud)
ghci> takeUntilTime 1000000 [x | x <- [1..], x == 0]
[]
(1.02 secs, 153111264 bytes)
ghci> takeUntilTime 1000000 [maximum [y `mod` x | y <- [1..100000]] | x <- [1..]]
[0,1,2,3]
(1.00 secs, 186234264 bytes)


Rob*_*oli 6

我想你想要的是:System.Timeout

它允许IO事件超时.它有一个类型为的函数:

timeout :: Int -> IO a -> IO (Maybe a)
Run Code Online (Sandbox Code Playgroud)

我认为你应该能够使用它.我这样做的方法是使用超时功能和迭代深化方法将更多内容添加到您的函数中,直到它工作.这样,当一个人终于达到超时时,你知道你已经走得足够远了.