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