I'm using Conduit to parse some data in a stream-like manner. At some point in the stream I require every 12th element. Is there a convenient way to do this?
I'm currently explicitly waiting for 12 elements just to return the first element:
get12th :: Monad m => Conduit Int m Int
get12th = loop
where
loop = do
v1 <- await
_ <- await
_ <- await
_ <- await
_ <- await
_ <- await
_ <- await
_ <- await
_ <- await
_ <- await
_ <- await
_ <- await
case v1 of
Nothing -> return ()
Just x -> do
yield x >> loop
It does work, but I'm wondering if this is the best way to do it.
Thanks to Alec, Chad Gilbert and Michael Snoyman, I've come to the following solution:
get12th :: Monad m => Conduit Int m Int
get12th = loop
where loop = do
v <- await
case v of
Just x -> yield x >> CL.drop 11 >> loop
Nothing -> return ()
This solution uses the drop
function to get rid of the duplicate awaits. It yields the first value as soon as it receives it, before waiting for the other values.