Hi,

Here’s a simple program I wrote to test out if Haskell’s recursion within a do-block will stack overflow:

```
count :: Int -> IO Int
count it
| it <= 0 = pure 0
| otherwise =
do
n <- count (it - 1)
pure (n + 1)
```

surprisingly it doesn’t seem to stack overflow even for largish numbers like 1000000.

The equivalent Scala code in a for-comprehension:

```
import cats.effect.IO
val count: Int => IO[Int] = {
case 0 => IO.pure(0)
case it =>
for {
n <- count (it - 1)
} yield (n + 1)
}
count(10000).unsafeRunSync
```

stack overflows at numbers around 10,000.

My question is about how Haskell implements this recursion in a do block such that it doesn’t stack overflow. I presume it’s related to thunks, beyond that I am not sure how it works. Any help would be appreciated. I looked around Google but couldn’t find anything related… maybe I’m looking for the wrong keywords.

Cheers,

Sanj