मैं एक ऐसा फ़ंक्शन लिखना चाहता हूं जिसमें समय सीमा (सेकंड में) और एक सूची हो, और समय सीमा के भीतर जितनी संभव हो सके सूची के कई तत्वों की गणना करें।एक निश्चित समय में जितनी संभव हो सके उतनी सूची की गणना करें
मेरा पहला प्रयास पहले निम्नलिखित समारोह, जो कई बार एक शुद्ध गणना लिखने के लिए था और समय परिणाम के साथ गुजरे रिटर्न:
import Control.DeepSeq
import System.CPUTime
type Time = Double
timed :: (NFData a) => a -> IO (a, Time)
timed x = do t1 <- getCPUTime
r <- return $!! x
t2 <- getCPUTime
let diff = fromIntegral (t2 - t1)/10^12
return (r, diff)
मैं तो समारोह मैं इस के मामले में चाहते हैं परिभाषित कर सकते हैं:
timeLimited :: (NFData a) => Time -> [a] -> IO [a]
timeLimited remaining [] = return []
timeLimited remaining (x:xs) = if remaining < 0
then return []
else do
(y,t) <- timed x
ys <- timeLimited (remaining - t) xs
return (y:ys)
हालांकि यह बिल्कुल सही नहीं है। समय त्रुटियों और फ़्लोटिंग पॉइंट त्रुटियों को अनदेखा करने के बावजूद, यह दृष्टिकोण कभी भी शुरू होने के बाद सूची के तत्व की गणना को रोकता नहीं है, जिसका अर्थ यह है कि यह (और वास्तव में, सामान्य रूप से) अपनी समय सीमा को खत्म कर सकता है।
, तो इसके बजाय मैं एक समारोह है कि सकता है शॉर्ट सर्किट मूल्यांकन करता है, तो यह बहुत लंबा ले लिया था था:
timeLimited' :: Time -> [a] -> IO [a]
timeLimited' remaining [] = return []
timeLimited' remaining (x:xs) = do
result <- timeOut remaining x
case result of
Nothing -> return []
Just (y,t) -> do
ys <- timeLimited' (remaining - t) xs
return (y:ys)
:
timeOut :: Time -> a -> IO (Maybe (a,t))
timeOut = undefined
तो मैं समारोह है कि मैं वास्तव में चाहते लिख सकता है मेरे प्रश्न हैं:
- मैं
timeOut
कैसे लिखूं? - क्या
timeLimited
फ़ंक्शन लिखने का कोई बेहतर तरीका है, उदाहरण के लिए, जो एक बार फ़्लोटिंग पॉइंट त्रुटि से संचित फ्लोटिंग पॉइंट त्रुटि से पीड़ित नहीं होता है?
क्या आप दो धागे नहीं चला सकते हैं जहां एक थ्रेड उस समय की गणना करता है और गणना की थ्रेड को मारने के बाद गणना समय को मार देता है? –
शायद। मैंने हास्केल में बहुत अधिक समवर्ती कोड नहीं लिखा है। आंशिक रूप से मूल्यांकन की गई सूची को वापस करने में सक्षम कैसे होगा? –
मैं शायद सूची को एक टीवीर में डाल दूंगा और हर नए नोड को दूंगा। बस देखा कि एसटीएम.TVar में 'रजिस्टरडेले' नामक एक फ़ंक्शन है जो दो धागे सिंक्रनाइज़ करने के लिए सहायक भी हो सकता है। –