के अंदर तो मेरी समस्या निम्नानुसार है। मैं आरडीबी फाइलों के लिए एक स्ट्रीमिंग पार्सर को लागू करने की कोशिश कर रहा हूं (रेडिस का उत्पादन करने वाली डंप फाइलें)। मैं mapM_ के समान फ़ंक्शन को कार्यान्वित करना चाहता हूं, जिससे मैं कर सकता हूं, डंप फ़ाइल में प्रदर्शित प्रत्येक ऑब्जेक्ट को प्रिंट करें क्योंकि इसे पार्स किया गया है। हालांकि, मैं इसे स्थिर स्थान पर संचालित करने के लिए प्रतीत नहीं कर सकता। मुझे लगता है कि क्या हो रहा है कि मैं एक महान आईओ() गेट मोनाड के अंदर थंक बना रहा हूं, गेट मोनड से लौट रहा हूं और फिर आईओ को निष्पादित कर रहा हूं। क्या मेरी वस्तुओं को स्ट्रीम करने के लिए वैसे भी है क्योंकि उन्हें मुद्रित करने के लिए पार्स किया गया है और फिर उन्हें त्याग दिया गया है? मैंने गणक और कंडिटेक्ट्स की कोशिश की है लेकिन मैंने कोई वास्तविक लाभ नहीं देखा है। यहां मेरे पास अब तक है:आईओओ गेट मोनाड
loadObjs_ :: (Monad m) => (Maybe Integer -> BL8.ByteString -> RDBObj -> Get (m a)) -> Get (m a)
loadObjs_ f = do
code <- lookAhead getWord8
case code of
0xfd -> do
skip 1
expire <- loadTime
getPairs_ f (Just expire)
0xfc -> do
skip 1
expire <- loadTimeMs
getPairs_ f (Just expire)
0xfe -> f Nothing "Switching Database" RDBNull
0xff -> f Nothing "" RDBNull
_ -> getPairs_ f Nothing
getPairs_ :: (Monad m) => (Maybe Integer -> BL8.ByteString -> RDBObj -> Get (m a)) -> Maybe Integer -> Get (m a)
getPairs_ f ex = do
!t <- getWord8
!key <- loadStringObj False
!obj <- loadObj t
!rest <- loadObjs_ f
!out <- f ex key obj
return (out >> rest)
(loadObj does the actual parsing of a single object but I believe that whatever I need to fix the streaming to operate in constant or near-constant memory is at a higher level in the iteration than loadObj)
getDBs_ :: (Monad m) => (Maybe Integer -> BL8.ByteString -> RDBObj -> Get (m a)) -> Get (m a)
getDBs_ f = do
opc <- lookAhead getWord8
if opc == opcodeSelectdb
then do
skip 1
(isEncType,dbnum) <- loadLen
objs <- loadObjs_ f
rest <- getDBs_ f
return (objs >> rest)
else f Nothing "EOF" RDBNull
processRDB_ :: (Monad m) => (Maybe Integer -> BL8.ByteString -> RDBObj -> Get (m a)) -> Get (m a)
processRDB_ f = do
header <- getBytes 9
dbs <- getDBs_ f
eof <- getWord8
return (dbs)
printRDBObj :: Maybe Integer -> BL8.ByteString -> RDBObj -> Get (IO())
printRDBObj (Just exp) key obj = return $ (print ("Expires: " ++ show exp) >>
print ("Key: " ++ (BL8.unpack key)) >>
print ("Obj: " ++ show obj))
printRDBObj Nothing key RDBNull = return $ (print $ BL8.unpack key)
printRDBObj Nothing key obj = return $ (print ("Key: " ++ (BL8.unpack key)) >>
print ("Obj: " ++ show obj))
main = do
testf <- BL8.readFile "./dump.rdb"
runGet (processRDB_ printRDBObj) testf
सभी को अग्रिम धन्यवाद।
बेस्ट, एरिक
संपादित करें: यहाँ आलसी सूची पर आईओ एक आलसी सूची में वस्तुओं को पार्स और फिर करने के लिए अपने प्रयास है।
processRDB :: Get [RDBObj]
processRDB = do
header <- getBytes 9
dbs <- getDBs
eof <- getWord8
return (dbs)
main = do
testf <- BL8.readFile "./dump.rdb"
mapM_ (print . show) $ runGet processRDB testf
क्या आपने http://hackage.haskell.org/package/binary-strict की कोशिश की है? –
मैंने बाइनरी-सख्त कोशिश नहीं की है, लेकिन मैंने अनाज के सख्त होने का कोई फायदा नहीं उठाया। –
आप इसे कठोर बनाना नहीं चाहते हैं, आप इसे आलसी बनाना चाहते हैं। कहीं कहीं सख्त हो रहा है। लेकिन मैं प्रासंगिक पैकेजों के आस-पास अपने रास्ते को अच्छी तरह से नहीं जानता। –