Re: [Haskell-cafe] Problems with iteratees

I agree with Maciej Wos' diagnosis and solution. I'd like to point out that the Tiff library has to do a similar processing: use an iteratee to read bytes from the outer stream and to produce elements for the inner stream (e.g., signed 32-bit integers). In your version of the Iteratee library, please look at Data/Iteratee/Codecs/Tiff.hs and search for the following fragment: -- Read the array of long integers -- of 1 element: the offset field contains the value read_value typ e' 1 | typ == TT_long || typ == TT_slong = ... -- of n elements read_value typ e' count | typ == TT_long || typ == TT_slong = do offset <- endianRead4 e' return . Just . TEN_INT $ \iter_int -> return $ do Iter.seek (fromIntegral offset) let iter = convStream (liftM (either (const Nothing) (Just . (:[]) . conv_long typ)) (checkErr (endianRead4 e'))) iter_int Iter.joinI $ Iter.joinI $ Iter.takeR (4*count) iter Of relevance is the line that contains convStream. Please notice (const Nothing) that Maciej was talking about. The newer version has a somewhat more convenient sequence_stream function, which creates a nested stream using the supplied iteratee to read from the outer stream and produce an element for the inner stream. The function is particularly useful if you read the inner stream all the way, until it is exhausted. Here is how the above read_value clause looks now -- of n elements read_value typ count | typ == TT_long || typ == TT_slong = do offset <- endian_read4 let converter = endian_read4 >>= return . conv_long typ return . Just . TEN_INT $ \iter_int -> do seek_stream (fromIntegral offset) runI =<< takeR (4*count) (sequence_stream converter iter_int)
participants (1)
-
oleg@okmij.org