The reason why such operations doesn't exist on stream is because streams may encapsulate resources. For example, Repo.stream is a lazy database query. Having operations such as Stream.head(...) | Stream.tail(...) means you would have to execute the query twice, one to get the head, and another for the tail, which can be very wasteful in those cases.
You probably could be tackled without head and tail, by first applying all transforms to streams and then running it:
~e[*/10]
|> Crontab.Scheduler.get_next_run_dates()
|> Stream.each(fn date ->
callback.(date)
end)
|> Stream.run()
The stream programming model requires you to think about working with the collection as a whole, instead of item by item.