Imagine you need to fold over a sequence, and want to know also the intermediate values at several points along the range. This is what I've used for this:
[a,b,c] = map fst . tail $ chain [g i, g j, g k] (zero, sequence)
g :: Integer -> (a,b) -> (a,b)
chain (f:fs) x = x : chain fs (f x)
chain [] x = [x]
The function g
consumes a specified portion of an input sequence (of length i
, j
, etc.), starting with some initial value and producing results of the same type, to be fed into the next invocation. Consuming the sequence several times for different lengths starting over from the start and same initial value would be inefficient, both time and space-wise of course.
So on the one hand we fold over this sequence of integers - interim points on the sequence; on the other hand we iterate this function, g
. What is it? Am I missing something basic here? Can this be somehow expressed with the regular repertoire of folds, etc.?
EDIT: Resolved: the above is simply
[a,b,c] = map fst . tail $ scanl (flip g) (zero, sequence) [i, j, k]
interesting how a modifiable iteration actually is folding over the list of modifiers.
Try scanl
: http://www.haskell.org/hoogle/?hoogle=scanl
scanl is similar to foldl, but returns a list of successive reduced values from the left:
scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]
Note that
last (scanl f z xs) == foldl f z xs
To elaborate on Marcin's comment, you basically want:
intermediates = scanl step zero sequence
map (\n -> intermediates !! n) [i, j, k]
step
is not g
, but rather just the part of g
that consumes a single element of the list sequence
.
Also, accept Marcin's as the correct answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With