I recently found use for the following Haskell functions:
feed :: (a -> (a, b)) -> a -> Int -> (a, [b])
feed f input 0 = (input, [])
feed f input n
| n < 0 = error "feed f input n: n < 0"
| otherwise = (final, out:prev)
where (next, out) = f input
(final, prev) = feed f next $ pred n
nest :: (a -> a) -> a -> Int -> a
nest f x 0 = x
nest f x n
| n < 0 = error "nest f x n: n < 0"
| otherwise = f $ nest f x $ pred n
feed
cycles a function through some input a
, with the function returning a new input for the next call, as well as "emitting" an output, which is collected. nest
works the same way, but doesn't let functions emit
anything.
This looks awfully "Monadic" to me, and it seems to me like something from Control.Monad
should already be doing this (I've caught myself trying to re-implement stuff like sequence
, mapM
, etc., out of necessity before, since I'm a beginner with Haskell and I don't quite know what's in the library and what's not.
Does something like the above (perhaps in a more general setting?) already exist? I've looked through the docs (at least the one's I'm familiar with), and can't find anything, though this seems like a common pattern. Example usage:
let pick10 rng = feed (swap . randomR (1, 10)) rng 10
feed f next $ pred (n - 1)
at the end of thefeed
function?pred (n - 1) = n - 2
? That would err on odd numbers.prev
(the variable) insted ofpred
(the function). I thought you needed to decrement the variable but you actually already do.