You're welcome!

On 5/15/14, 5:25 PM, Alex Rozenshteyn wrote:
I realized that just as I was posting the code. Thanks.


On Thu, May 15, 2014 at 6:29 PM, Gabriel Gonzalez <[email protected] <mailto:[email protected]>> wrote:

    Have you considered using a `Pipe` instead of a `Fold`?  In other
    words:

        interesting :: Int -> (a -> Bool) -> Pipe a [a] m r

    It seems like a more natural fit for your problem. Basically it
    uses `await` to get the next element, and it `yield`s each
    successive stanza that it computes.


    On 5/14/14, 5:31 PM, Alex Rozenshteyn wrote:
    What I ended up writing (not cleaned up at all, and not exactly
    solving the problem posed; CRAPLed
    <http://matt.might.net/articles/crapl/>, if you will) can be
    found here: http://lpaste.net/104155

    I used a monadic fold and the Writer monad, though looking back
    on it, I feel like Pipes would be a natural fit. I'm keeping a
    buffer just big enough to know what to output at each step in the
    consumption of the list.

    One problem I had was that I misremembered how scan works; for
    some reason I thought that `scan list` was `tails` and not `inits`.



    On Wed, May 14, 2014 at 7:50 PM, Gabriel Gonzalez
    <[email protected] <mailto:[email protected]>> wrote:

        Actually, there's not a good way to do this using `Foldl`
        because the fold does not have access to elements ahead of it
        in the stream.

        However, there's a pretty simple solution in terms of
        ordinary list functions:

            import Data.List (tails)


            takeInteresting :: Int -> (a -> Bool) -> [a] -> [a]
            takeInteresting n pred = go n
              where
                -- go :: Int -> [a] -> [a]
                go n as =
                    if n <= 0
                    then []
                    else let (prefix , suffix ) = break pred as
                             (prefix', suffix') = case suffix of
                                 [] -> (prefix, suffix)
                                 s:uffix -> (prefix ++ [s], uffix)
                         in  prefix' ++ go (n - 1) suffix'

            scanInteresting :: Int -> (a -> Bool) -> [a] -> [[a]]
            scanInteresting n pred = map (takeInteresting n pred) . tails

        Here's an example usage:

            >>> scanInteresting 2 (== 0) [1, 2, 0, 3, 4, 0, 5, 6, 0]
        
[[1,2,0,3,4,0],[2,0,3,4,0],[0,3,4,0],[3,4,0,5,6,0],[4,0,5,6,0],[0,5,6,0],[5,6,0],[6,0],[0],[]]




        On 5/11/14, 9:40 AM, Alex Rozenshteyn wrote:
        Only tangentially related, but still, close enough that I
        feel like it's a follow-up, and tricky enough that I feel
        like I should ask someone else.

        This is a Foldl question, so if there's a better place to
        ask it, please let me know.

        Some context, which can mostly be safely ignored, but I'm
        providing for motivation in case my explanation is not clear:

        I'm trying to make Anki flashcards to memorize "The Love
        Song of J. Alfred Prufrock". My input format is the text of
        the poem (slightly preprocessed), and my output formate is a
        newline separated file with some formatting on each line.
        Each line defines a flashcard with a hole (a cloze
        deletion). I would like sufficient context; in this case,
        it's 5 lines or to the beginning of the stanza, whichever is
        longer.

        </context>

        What I want to write is a variant on a take function that
        takes the first n "interesting" elements and any
        uninteresting ones interspersed; that is

        takeInteresting :: Int -> (a -> Bool) -> [a] -> [a]

        such that

        length . filter p . takeInteresting n p == n
        isPrefixOf (takeInteresting n p xs) xs

        If I understand correctly, I can write this as a fold and
        then use a scan to apply it at every starting point.

        My question is how best to write this fold.

        My ad-hoc approach was to use a decorate-doStuff-undecorate
        pattern where I would count the number of interesting
        elements, but it wasn't very compositional; I expect there's
        a better approach.

        Thank you.


        On Thu, Mar 6, 2014 at 12:43 AM, Gabriel Gonzalez
        <[email protected] <mailto:[email protected]>> wrote:

            The trick is to combine `pipes` with the `foldl`
            library.  In fact, given any `Fold`, you can convert it
            into a scanning pipe like this:

                convert :: Monad m => Fold a b -> Pipe a b m r
                convert = Control.Foldl.purely Pipes.Prelude.scan

            So now you have a smaller problem: write a fold for a
            moving average of a stream of numbers.  It turns out
            that there is a nice way to do this in O(1) space if you
            do an exponential moving average:

            http://lpaste.net/100765

            You can also do an ordinary moving average, too, but
that requires O(N) space (where N is the window size). It basically involves storing the last N elements as the
            fold's internal state.

            The `foldl` library is easy to learn.  Just read the
            module header here and the documentation for the `Fold`
            type:

            
http://hackage.haskell.org/package/foldl-1.0.2/docs/Control-Foldl.html

            Now, technically, you could do all of this without using
            the `foldl` library at all, just by passing the folding
            logic directly to `Pipes.Prelude.scan`, but by using
            `foldl` you make it really easy to add additional
            metrics to your `Fold` while still passing over the data
            just once.


            On 3/5/2014 8:01 AM, Alex Rozenshteyn wrote:
            I feel like I must be missing something rather basic,
            but I have been trying to figure out how to use pipes
            to compute a moving average of a stream of numbers.
            I've written code to do the EWMA, but I can't figure
            out how to do the sliding window. It doesn't help that
            I'm a bit of a pipes beginner.

            Advice is welcome and appreciated.

            Thank you.
-- 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
            [email protected]
            <mailto:[email protected]>.

            To post to this group, send email to
            [email protected]
            <mailto:[email protected]>.




-- Alex R




-- Alex R




--
          Alex R

--
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 [email protected].
To post to this group, send email to [email protected].

Reply via email to