This is another way you can look at your problem. countDown is concerned with repeatedly calling a function, decrementing a counter, and inserting some time in between the function calls – that's a lot for one function.
I'll be abstracting some of this complexity away with delay and effect and repeat. You'll notice that countDown requires zero logic once we've abstracted to this point – this is sometimes why people say functional programs can take on a declarative resemblance.
const delay = ms => x =>
new Promise (r => setTimeout (r, ms, x))
const effect = f => x =>
(f (x), x)
const repeat = n => f => x =>
n === 0 ? x : repeat (n - 1) (f) (f (x))
const countDown = (x, ms, f) =>
repeat (x)
(p => p.then (effect (f)) .then (delay (ms)) .then (x => x - 1))
(Promise.resolve (x))
countDown (5, 1000, console.log)
.then (x => console.log ('done', x))
This is another way you can look at your problem. countDown is concerned with repeatedly calling a function, decrementing a counter, and inserting some time in between the function calls – that's a lot for one function.
I'll abstracting some of this complexity away with delay and effect and repeat. You'll notice that countDown requires zero logic once we've abstracted to this point – this is sometimes why people say functional programs can take on a declarative resemblance.
const delay = ms => x =>
new Promise (r => setTimeout (r, ms, x))
const effect = f => x =>
(f (x), x)
const repeat = n => f => x =>
n === 0 ? x : repeat (n - 1) (f) (f (x))
const countDown = (x, ms, f) =>
repeat (x)
(p => p.then (effect (f)) .then (delay (ms)) .then (x => x - 1))
(Promise.resolve (x))
countDown (5, 1000, console.log)
.then (x => console.log ('done', x))
This is another way you can look at your problem. countDown is concerned with repeatedly calling a function, decrementing a counter, and inserting some time in between the function calls – that's a lot for one function.
I'll be abstracting some of this complexity away with delay and effect and repeat. You'll notice that countDown requires zero logic once we've abstracted to this point – this is sometimes why people say functional programs can take on a declarative resemblance.
const delay = ms => x =>
new Promise (r => setTimeout (r, ms, x))
const effect = f => x =>
(f (x), x)
const repeat = n => f => x =>
n === 0 ? x : repeat (n - 1) (f) (f (x))
const countDown = (x, ms, f) =>
repeat (x)
(p => p.then (effect (f)) .then (delay (ms)) .then (x => x - 1))
(Promise.resolve (x))
countDown (5, 1000, console.log)
.then (x => console.log ('done', x))
This is another way you can look at your problem. countDown is concerned with repeatedly calling a function, decrementing a counter, and inserting some time in between the function calls – that's a lot for one function.
I'll abstracting some of this complexity away with delay and effect and repeat. You'll notice that countDown requires zero logic once we've abstracted to this point – this is sometimes why people say functional programs can take on a declarative resemblance.
const delay = ms => x =>
new Promise (r => setTimeout (r, ms, x))
const effect = f => x =>
(f (x), x)
const repeat = n => f => x =>
n === 0 ? x : repeat (n - 1) (f) (f (x))
const countDown = (x, ms, f) =>
repeat (x)
(p => p.then (effect (f)) .then (delay (ms)) .then (x => x - 1))
(Promise.resolve (x))
countDown (5, 1000, console.log)
.then (x => console.log ('done', x))