Hi,

I'm wondering if it's possible to use a pipes-like stream to express 
"contextual" filtering of elements. For example, taking a simplistic view 
of a block comment as a groups lines such that the first line that begins 
with "{-" and the last line begins with "-}", I'd like to be able to filter 
a stream like:

[ "foo"
, "{- hi"
, "there -}"
, "bar"
, "{- whoops"
]

into

[ "foo"
, "bar"
]

Using the *streaming *library (similar to pipes + pipes-group + 
pipes-parse), my first attempt was something like:

import Streaming
import qualified Streaming.Prelude as S

filterBlockComments :: forall m r. Stream (Of String) m r -> Stream (Of 
String) m r
filterBlockComments s0 = do
    -- s0 == ["foo", "{- hi", "there -}", "bar", "{- whoops"]

    -- yield ["foo"], leaving
    -- s1 == ["{- hi", "there -}", "bar", "{- whoops"]
    s1 :: Stream (Of String) m r
        <- S.span (\line -> not ("{-" `isPrefixOf` line)) s0

    -- break s1 into (["{- hi"], ["there -}", "bar", "{- whoops"]),
    -- then drop the first element of the second half, leaving
    -- (["{- hi"], ["bar", "{- whoops"])
    let s2 :: Stream (Of String) m (Stream (Of String) m r)
        s2 = fmap (S.drop 1) (S.break (\line -> "-}" `isSuffixOf` line) s1)

    -- run s2 without yielding its elements, leaving
    -- s3 == ["bar", "{- whoops"]
    s3 <- lift (S.effects s2)

    -- loop
    filterBlockComments s3
    
However, this doesn't terminate, for reasons I haven't quite figured out 
other than I'm doing streaming "wrong". So, is there a more idiomatic way 
to write such a function?

Thanks,
Mitchell
    
    
    

-- 
You received this message because you are subscribed to the Google Groups 
"Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to haskell-pipes+unsubscr...@googlegroups.com.
To post to this group, send email to haskell-pipes@googlegroups.com.

Reply via email to