Your code calls await
twice in a row. What that says is "give me the next two values in the stream, and do not put them back in the stream." When you do this repeatedly, you are essentially breaking your stream into 2-value chunks. Using your original list, you are basically getting tuples that look like:
[(1,2),(3,4),(5,2)] -- final 3 is lost since it has no pair
The issue is that you 2,3 sequences always fall between two of these tuples. It seems to me like the algorithm you really want is:
- Check if the first two values in the stream match 2,3.
- Proceed forward in the stream by one element and repeat.
Currently, you're stepping forward two elements in the stream.
Fortunately, there's an easy solution to this problem: instead of using await
to get the second value, which removes it from the stream at the same time, use peek
, which will look at the value and put it back. If you replace b <- await
with b <- CL.peek
, you should get the behavior you're looking for.
UPDATE
Just to give a little bit more information. Under the surface, peek
is implemented on top of two primitives in conduit: await
and leftover
, like so:
peek = do
mx <- await
case mx of
Nothing -> return Nothing
Just x -> do
leftover x
return (Just x)
There's nothing magical about this ability to look ahead by 1 element. You can similarly look ahead 2 elements. The only trick is making sure to do the leftovers in the correct order:
peek2 = do
mx <- await
my <- await
maybe (return ()) leftover my
maybe (return ()) leftover mx
return (mx, my)