Let's take a function of type `(Monad m) => a -> m a`

. For example:

```
ghci> let f x = Just (x+1)
```

I'd like to be able to apply it any number of times. The first thing I tried was

```
ghci> let times n f = foldr (>=>) return $ replicate n f
```

The problem is that it won't work for large `n`

:

```
ghci> 3 `times` f $ 1
Just 4
ghci> 1000000 `times` f $ 1
Just *** Exception: stack overflow
```

It doesn't work also the other way:

```
ghci> let timesl n f = foldl' (<=<) return $ replicate n f
ghci> 3 `timesl` f $ 1
Just 4
ghci> 1000000 `timesl` f $ 1
Just *** Exception: stack overflow
```

Actually, what works is using `($!)`

strictness operator

```
ghci> let timesStrict n f = foldr1 ((>=>) . ($!)) $ replicate n f
ghci> 3 `timesStrict` f $ 1
Just 4
ghci> 10000000 `timesStrict` f $ 1
Just 10000001
```

Is there a nicer or more idiomatic solution? Or probably a stricter one? I still easily get stack overflows if `f`

is a heavy-weight function.

*UPD:* I found that writing `times`

in a pointful form does not solve the problem of composing heavy-weight monadic actions neither. This works for f x = Just (x+1) but fails in the real world:

```
times f 0 a = return a
times f i a = (f $! a) >>= times f (i - 1)
```